【发布时间】:2012-08-07 15:16:53
【问题描述】:
我正在尝试使用以下代码进行一种类型处理函数注册:
types = {}
def type_handler(name):
def wrapper(f):
types[name] = f
return f
return wrapper
@type_handler('a')
def handle_a(a):
...
@type_handler('b'):
def handle_b(b):
...
def handle(x):
types[x.name](x)
这很好用,但现在我希望它在一个类中工作。
我试过这个:
class MyClass(object):
types = {}
def type_handler(name):
def wrapper(f):
types[name] = f ## global name 'types' is undefined
return f
return wrapper
@type_handler('a')
def handle_a(self, a):
...
@type_handler('b'):
def handle_b(self, b):
...
def handle(self, x):
self.types[x.name](self, x)
但上面写着global name 'types' is undefined。
我尝试将其更改为
def type_handler(name):
def wrapper(f):
MyClass.types[name] = f ## global name 'MyClass' is undefined
return f
return wrapper
但现在是global name 'MyClass' is undefined。
我能做些什么来完成这项工作?
我知道我可以这样做:
def handle(self, x):
self.__getattribute__('handle_%s' % x.name)(self, x)
但我更喜欢函数注册而不是基于名称的查找。
【问题讨论】:
-
您所看到的行为的原因是在名称查找过程中跳过了类范围 - 请参阅 The scope of names defined in class block doesn't extend to the methods' blocks. Why is that? 以获得进一步的解释。
-
有几种方法可以解决这个问题,但如果不知道这个装饰器的上下文是什么,我真的无法给出一个好的方法建议。我的一般建议是少用魔法。