当你装饰一个方法时,它还没有绑定(bind)到类,因此还没有 im_class
属性。我正在寻找一种方法来获取有关装饰器内部类的信息。我试过这个:
import types
def decorator(method):
def set_signal(self, name, value):
print name
if name == 'im_class':
print "I got the class"
method.__setattr__ = types.MethodType(set_signal, method)
return method
class Test(object):
@decorator
def bar(self, foo):
print foo
但它不打印任何东西。
我可以想象这样做:
class Test(object):
@decorator(klass=Test)
def bar(self, foo):
print foo
但如果我能避免它,它会让我开心。
最佳答案
__setattr__
仅在显式 object.attribute =
赋值时调用;构建类不使用属性分配,而是构建字典 (Test.__dict__
)。
要访问类(class),您有几个不同的选择:
改用类装饰器;它将在构建完成后传递给完成的类,您可以通过在类中替换它们(装饰)来装饰该类的各个方法。您可以结合使用函数装饰器和类装饰器来标记要装饰的方法:
def methoddecoratormarker(func): func._decorate_me = True return func def realmethoddecorator(func): # do something with func. # Note: it is still an unbound function here, not a method! return func def classdecorator(klass): for name, item in klass.__dict__.iteritems(): if getattr(item, '_decorate_me', False): klass.__dict__[name] = realmethoddecorator(item)
当然,您可以使用元类而不是类装饰器来实现相同的目的。
作弊并使用
sys._getframe()
从调用框架中检索类:import sys def methoddecorator(func): callingframe = sys._getframe(1) classname = callingframe.f_code.co_name
请注意,您只能检索该类的名称;该类本身此时仍在构建中。您可以将项添加到
callingframe.f_locals
(一个映射),它们将成为新类对象的一部分。每当调用方法时访问
self
。self
毕竟是对实例的引用,self.__class__
至少是函数定义的原始类的子类中。
关于python - 有没有办法将装饰器应用于需要类信息的 Python 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12778533/