目标:创建一个decorator,它可以修改它所使用的范围。在
如果有效:
class Blah(): # or perhaps class Blah(ParentClassWhichMakesThisPossible)
def one(self):
pass
@decorated
def two(self):
pass
>>> Blah.decorated
["two"]
为什么?本质上,我想编写一些类来维护方法的特定字典,这样我就可以在每个类的基础上检索不同类型的可用方法的列表。呃。。。。。在
我想这样做:
^{pr2}$
Tags:
问题是,在调用
decorated
修饰符时,没有对象Blah
但是:类对象是在类主体完成执行之后生成的。最简单的方法是让decorated
将信息存储在“其他地方”,例如函数属性,然后最后一次传递(类装饰器或元类)将这些信息重新放入所需的字典中。在类decorator更简单,但它们不会被继承(因此它们不会来自父类),而元类则是继承的,因此如果您坚持继承,则必须是元类。最简单的方法是使用类修饰符和Q开头的“list”变体,而不是后面的“dict”变体:
现在
^{pr2}$给你在Q的第一部分中请求的},当然,在类decorator中将
Blah.decorated
列表。相反,正如你在Q的第二部分中所请求的那样,构建dict只意味着在上面的代码中将decorated.append(name)
改为{decorated
初始化为空dict而不是空列表。在元类变体将使用元类的
__init__
在构建类主体之后执行基本相同的后处理元类的__init__
获取与类主体相对应的dict作为其最后一个参数(但是您必须通过适当处理基类的类似dict或list来支持继承)。因此,元类方法在实践中只是比类装饰器“稍微”复杂一些,但从概念上讲,大多数人觉得要困难得多。如果需要的话,我会给出元类的所有细节,但是如果可行的话,我建议使用更简单的类装饰器。在您可以使用类修饰符(在Python2.6中)或元类执行您想要的操作。类装饰器版本:
元类版本将是:
^{pr2}$请注意,这两种方法都不能满足您的要求(修改调用的名称空间),因为它是脆弱的、困难的,而且常常是不可能的。相反,它们都通过类修饰符或元类的
__init__
方法对类进行后处理,方法是检查所有属性并填充rules
属性。两者之间的区别在于元类解决方案在Python2.5和更早版本(下至2.2)中工作,并且元类是继承的。对于decorator,子类必须分别应用decorator(如果它们想设置rules属性)这两种解决方案都没有考虑继承性,它们在查找标记为规则的方法时不查看父类,也不查看父类
rules
属性。如果这是你想要的话,你也不难做到这一点。在相关问题 更多 >
编程相关推荐