函数与方法装饰器

仅在有显著优势时, 审慎地使用装饰器. 避免使用 staticmethod. 减少使用 classmethod.

定义:

装饰器(也就是@标记)作用在函数和方法上. 常见的装饰器是 @property, 用于把方法转化为动态求值的属性. 不过, 也可以用装饰器语法自行定义装饰器. 具体地说, 若有一个函数 my_decorator , 下面两段代码是等效的:

class C(object):
   @my_decorator
   def method(self):
       # 函数体 ...
class C(object):
    def method(self):
        # 函数体 ...
    method = my_decorator(method)

优点:

优雅地实现函数的变换; 这种变换可用于减少重复的代码, 或帮助检查不变式 (invariant).

缺点:

装饰器可以在函数的参数和返回值上执行任何操作, 这可能产生意外且隐蔽的效果. 而且, 装饰是在定义对象时执行. 模块级对象(类、模块级函数)的装饰器在导入模块时执行. 当装饰器代码出错时, 很难恢复正常控制流.

结论:

仅在有显著优势时, 审慎地使用装饰器. 装饰器的导入和命名规则与函数相同. 装饰器的pydoc注释应清楚地说明该函数是装饰器. 请为装饰器编写单元测试.

避免装饰器自身对外界的依赖(即不要依赖于文件, 套接字, 数据库连接等), 因为执行装饰器时(即导入模块时. pydoc 和其他工具也会导入你的模块) 可能无法连接到这些环境. 只要装饰器的调用参数正确, 装饰器应该 (尽最大努力) 保证运行成功.

装饰器是一种特殊形式的”顶级代码”. 参见关于《Python风格规范》中“主程序”的章节.

不得使用 staticmethod, 除非为了兼容老代码库的 API 不得已而为之. 应该把静态方法改写为模块级函数.

仅在以下情况可以使用 classmethod: 实现具名构造函数(named constructor); 在类方法中修改必要的全局状态 (例如进程内共享的缓存等)。