这是一个元类,它将__getattr__函数从类定义添加回元类本身。这就避免了在多个地方定义函数,或者作为预先定义并单独添加到元类和类中的单独全局函数来定义。在class Meta(type):
def __new__(mcls, name, bases, dikt):
fgetattr = dikt.get('__getattr__')
if fgetattr is not None:
setattr(mcls, '__getattr__', fgetattr)
return super(Meta, mcls).__new__(mcls, name, bases, dikt)
class Generator(object):
__metaclass__ = Meta
def __getattr__(obj, name):
def f(self):
return "Result of %s for %r" % (name, self)
f.__name__ = name
if isinstance(obj, type):
setattr(obj, name, f)
else:
setattr(type(obj), name, f)
return getattr(obj, name)
与其通过动态函数的__get__描述符方法直接创建方法,不如将函数存储在dict类中,并依赖getattr返回正确的绑定/未绑定方法。随后的属性访问将使用类中的函数。由于类和实例都使用相同的__getattr__函数,因此需要进行isinstance检查,以确保将动态函数存储到类而不是实例中。在
在Python3中,将函数作为类的属性只返回函数,因为未绑定的方法已从语言中移除。另外,metaclass syntax已更改为类定义行中的关键字参数。在
测试:
^{pr2}$