我有一个类,我想在类中的列表中的所有方法,我希望它工作,即使我有两个同名的方法,我的问题是我无法访问类放到方法那里。 假设我有装饰师
def dec(func):
class = ????
class.methods.append(func)
return func
我有班级
class A(object):
methods = []
@dec
def a(self):
print 2
@dec
def a(self):
print 3
我希望能够做到
A.methods[0](A())
A.methods[1](A())
(A() becuase those methods need self)
或类似的东西
我已经阅读了很多像这样的问题,看起来我想要的并不是真的可能,因为调用装饰器时A不存在,但也许有一种方法来访问它的变量,因为装饰器在它内部运行?
答案 0 :(得分:1)
类对象本身仅在 body语句之后构造(class <classname>(<bases,>):
块中的所有语句都已执行。另一方面,decorators与它们的函数一起执行装饰。
您可以在列表中将希望方法添加到装饰器中:
class A(object):
methods = []
@dec(methods)
def a(self):
print 2
@dec(methods)
def a(self):
print 3
让装饰者使用该列表附加你的方法:
def dec(methodslist):
def decorator(f):
methodslist.append(f)
return f
return decorator
如果您使用的是Python 3,那么另一个选项是您使用自定义metaclass.__prepare__
class method的元类,它使用collections.defaultdict()
首先将所有属性收集到列表中,这样即使您仍然可以访问它们命名相同。然后你的装饰者只需要用额外的属性或其他东西“标记”每个函数对象。这有点多了。
当你想要调用这些函数时,你是对的,他们没有绑定,也不会为你传递self
。手动传入self
或绑定。函数是descriptor objects,调用它们的__get__
方法将它们绑定到实例:
for func in self.methods:
method = func.__get__(self)
method()
演示:
>>> def dec(methodslist):
... def decorator(f):
... methodslist.append(f)
... return f
... return decorator
...
>>> class A(object):
... methods = []
... @dec(methods)
... def a(self):
... print 2
... @dec(methods)
... def a(self):
... print 3
... def call_all(self):
... for func in self.methods:
... method = func.__get__(self)
... method()
...
>>> A().call_all()
2
3