Я не думаю, что вы можете делать то, что вы хотите делать с декоратором (быстрое редактирование: в любом случае, с декоратором метода).Декоратор вызывается, когда метод создается, что составляет до класса.Причина, по которой ваш код не работает, состоит в том, что класс не существует, когда вызывается декоратор.
Комментарий jldupont - это путь: если вы хотите установить атрибут класса , вы должны либо украсить класс, либо использовать метакласс.
РЕДАКТИРОВАТЬ: хорошо, увидев ваш комментарий, я могу подумать о решении из двух частей, которое может работать для вас.Используйте декоратор метода для установки атрибута метода , а затем используйте метакласс для поиска методов с этим атрибутом и установите соответствующий атрибут class :
def TaggingDecorator(method):
"Decorate the method with an attribute to let the metaclass know it's there."
method.my_attr = 'FOO BAR'
return method # No need for a wrapper, we haven't changed
# what method actually does; your mileage may vary
class TaggingMetaclass(type):
"Metaclass to check for tags from TaggingDecorator and add them to the class."
def __new__(cls, name, bases, dct):
# Check for tagged members
has_tag = False
for member in dct.itervalues():
if hasattr(member, 'my_attr'):
has_tag = True
break
if has_tag:
# Set the class attribute
dct['my_attr'] = 'FOO BAR'
# Now let 'type' actually allocate the class object and go on with life
return type.__new__(cls, name, bases, dct)
Вот и все.Используйте следующее:
class Foo(object):
__metaclass__ = TaggingMetaclass
pass
class Baz(Foo):
"It's enough for a base class to have the right metaclass"
@TaggingDecorator
def Bar(self):
pass
>> Baz.my_attr
'FOO BAR'
Честно, правда?Используйте подход supported_methods = [...]
.Метаклассы - это круто, но люди, которые должны поддерживать ваш код после вас, вероятно, будут вас ненавидеть.