我发现了很多关于装饰器和类的问题,以及访问正在装饰的类实例的问题。据我所知,装饰生成器无法访问对象实例,因为当时还没有创建任何对象。
尽管如此,如果装饰者使用一个类引用(我的意思是,接收cls),那么我可以访问一些类字段:
class Foo:
_tags = {}
@classmethod
def _tag(cls, tag_name):
def decorator(func):
def tmp(*args, **kwargs):
return func(*args, **kwargs)
cls._tags[tag_name] = func.__name__
return tmp
return decorator
这是子类的魅力所在,我可以写:
@Foo._tag("something")
def somethingelse():
pass
但这将信息存储在父类中(正如预期的那样),因为我们正在讨论类变量。
我想知道是否有一种方法可以实现类似的行为,但要保证每个子类都有自己的
_tags
所有物
我可以预见一些变通方法,比如在测试过程中解析源代码或检查函数
__init__
.但我在寻找一种更简单的方法,如果有这种方法的话。
编辑1:
为了更清楚,我想从子类修饰方法。因此,这是不可能的:
Class Bar (Foo):
@Bar._tag("method")
def method(self):
pass
因为处理器/编译器尚未完成类的创建。否则,提出的带有类/方法的两级字典的解决方案对我来说就足够了。
变通方法
我的装饰师:
@classmethod
def TAG(cls, name):
def decorator(func):
def tmp(*args, **kwargs):
return func(*args, **kwargs)
tmp._has_alias = name
return tmp
return decorator
在期间
__初始化__
,我得到了这些信息,并存储:
self._tags = {getattr(self, name).has_alias: name for name in dir(self) if callable(getattr(self, name)) and hasattr(getattr(self, name), "_has_alias")}