Python 进阶技巧
本文介绍了 Python 中一些较为高级但实际很常用的技巧,包括上下文管理器、动态导入、猴子补丁、鸭子类型。
上下文管理器
在任何一门编程语言中,文件的输入输出、数据库的连接断开、互斥锁的获得释放等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻则使得系统处理缓慢,重则会使系统崩溃。
为了解决这个问题,不同的编程语言都引入了不同的机制。而在 Python 中,对应的解决方式便是 上下文管理器(context manager),它可以确保用过的资源得到迅速释放,有效提高了程序的安全性。上下文管理器通常和 with 语句 一起使用,可以在极大程度上简化代码,例如:
1 |
|
示例:基于类的上下文管理器
1 |
|
动态导入
__import__()
内置函数用于动态加载类和函数,如果一个模块经常变化就可以使用 __import__()
来动态载入,问题是只会导入最高级的包或模块。
importlib
库的目的有两个:第一个目的是在 Python 源代码中提供 import
语句的实现(扩展了 __import__()
函数),第二个目的是使用户更容易导入他们的自定义模块。
importlib.import_module(name, package=None)
- 导入一个模块。
- 参数 name 指定了以绝对或相对导入方式导入什么模块(比如
pkg.mod
或..mod
)。 - 如果参数 name 使用相对导入方式,那么必须指定参数 packages 为要导入的包名,这个包名作为解析这个包名的锚点(比如
import_module(..mod, pkg.subpkg)
将会导入pkg.mod
)。
importlib.reload(module)
- 重新加载之前导入的模块。
- 参数 module 必须是一个之前已经成功导入过的模块对象。
示例:动态加载插件
1 |
|
猴子补丁
猴子补丁(Monkey Patch),也叫做 热补丁、程序运行过程中的补丁,允许在运行期间动态修改一个类或模块。
如果是自己写的代码,Monkey Patch 就毫无意义了,直接改源码就可以,Monkey Patch 的主要用途在于源码不宜直接修改。比如你要修复一个第三方 module 的 bug 或者进行特定的修改、扩展,通常来说有下面几种做法:
- 直接把源 package/module,复制一份到当前项目中,再改源码。但不推荐,因为会导致当前的项目代码管理上的混乱。
- 向原作者提 pull request,以修正 bug 或者其他。应该如此,但未必能联系到对方,联系到了对方未必修改,修改了未必很快能用上。
这个时候 Monkey Patch 的价值就出来了,不用改原始的 module 源码,就能达到自己期望的效果。代码示例如下:
1 |
|
鸭子类型
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
鸭子类型(Duck Typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口决定,而是由“当前方法和属性的集合”决定。鸭子类型在动态语言中常常使用,是用来实现多态的一种方式。
示例:使用 duck typing 实现多态
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!