装饰类初始器

class A:
    @configurable
    def __init__(self, a, b=2, c=3):
        pass

    @classmethod
    def from_config(cls, cfg):  # 'cfg' must be the first argument
        # Returns kwargs to be passed to __init__
        return {"a": cfg.A, "b": cfg.B}

python的装饰器

这种用法基本属于装饰器的标准写法——在函数func签名上方写“@decorator”(decorator代指装饰器名称)。

解释器在调用该func函数时,等同于执行:

func = decorator(func) # decorator生成一个将func函数包装后的函数并返回,并同名覆盖func
func()	# 调用上方decorator生成的函数`

“等同于”的说法可能不够准确,因为第一句func = decorator(func)是在函数声明处执行的,且只执行一次。

同样,上面configurable的例子,也是在configurable函数中,将传进来的__init__函数包装,此后调用__init__函数等同于调用configurable包装的函数。那么包装后的函数长什么样子呢,具体行为是:

检查入参是否含有cfg
如含有cfg,调用该类的from_config类方法(classmethod),将cfg转换成参数字典,调用__init__。
如无cfg,直接按原参数列表调用__init__。