Проблема в том, что во время вызова декоратора decorated
там есть нет объекта Blah
еще: объект класса создается после , когда тело класса завершает выполнение. Простейшим является decorated
сохранение информации «где-то еще», например атрибут функции, затем последний проход (декоратор класса или метакласс) собирает эту информацию в словарь по вашему желанию.
Декораторы классов проще, но они не наследуются (поэтому они не будут исходить от родительского класса), тогда как метаклассы наследуются - так что если вы настаиваете на наследовании, метакласс это должно быть. Проще всего, с декоратором класса и вариантом «list», который у вас есть в начале вашего Q, а не с вариантом «dict», который у вас будет позже:
import inspect
def classdecorator(aclass):
decorated = []
for name, value in inspect.getmembers(aclass, inspect.ismethod):
if hasattr(value, '_decorated'):
decorated.append(name)
del value._decorated
aclass.decorated = decorated
return aclass
def decorated(afun):
afun._decorated = True
return afun
сейчас
@classdecorator
class Blah(object):
def one(self):
pass
@decorated
def two(self):
pass
дает вам список Blah.decorated
, который вы запрашиваете в первой части вашего Q. Вместо этого, когда вы запрашиваете во второй части вашего Q, создаете дикт, просто означает изменение decorated.append(name)
на decorated[name] = value
в приведенном выше коде. и, конечно же, инициализация decorated
в декораторе класса пустым диктом, а не пустым списком.
Вариант метакласса будет использовать метакласс __init__
для выполнения, по существу, той же постобработки после построения тела класса - метакласс __init__
получает в качестве последнего аргумента диктовку, соответствующую телу класса (но вы Вам придется самостоятельно поддерживать наследование, соответствующим образом обращаясь с аналогичным диктатом или списком любого базового класса). Таким образом, метаклассовый подход на практике «несколько» сложнее, чем декоратор классов, но концептуально он кажется гораздо более сложным для большинства людей. Я дам все детали для метакласса, если они вам понадобятся, но я бы порекомендовал придерживаться более простого декоратора классов, если это возможно.