Ale*_*exH 4 python scope decorator
目标:制作一个可以修改其使用范围的装饰器.
如果有效:
class Blah(): # or perhaps class Blah(ParentClassWhichMakesThisPossible)
def one(self):
pass
@decorated
def two(self):
pass
>>> Blah.decorated
["two"]
Run Code Online (Sandbox Code Playgroud)
为什么?我本质上想要编写可以维护特定字典方法的类,这样我就可以在每个类的基础上检索不同类型的可用方法的列表.errr .....
我想做这个:
class RuleClass(ParentClass):
@rule
def blah(self):
pass
@rule
def kapow(self):
pass
def shazam(self):
class OtherRuleClass(ParentClass):
@rule
def foo(self):
pass
def bar(self):
pass
>>> RuleClass.rules.keys()
["blah", "kapow"]
>>> OtherRuleClass.rules.keys()
["foo"]
Run Code Online (Sandbox Code Playgroud)
您可以使用类装饰器(在Python 2.6中)或元类来执行您想要的操作.类装饰器版本:
def rule(f):
f.rule = True
return f
def getRules(cls):
cls.rules = {}
for attr, value in cls.__dict__.iteritems():
if getattr(value, 'rule', False):
cls.rules[attr] = value
return cls
@getRules
class RuleClass:
@rule
def foo(self):
pass
Run Code Online (Sandbox Code Playgroud)
元类版本将是:
def rule(f):
f.rule = True
return f
class RuleType(type):
def __init__(self, name, bases, attrs):
self.rules = {}
for attr, value in attrs.iteritems():
if getattr(value, 'rule', False):
self.rules[attr] = value
super(RuleType, self).__init__(name, bases, attrs)
class RuleBase(object):
__metaclass__ = RuleType
class RuleClass(RuleBase):
@rule
def foo(self):
pass
Run Code Online (Sandbox Code Playgroud)
请注意,这些都不符合您的要求(修改调用命名空间),因为它很脆弱,很难并且通常是不可能的.相反,它们都__init__
通过检查所有属性并填充rules
属性来对类进行后处理 - 通过类装饰器或元类的方法.两者之间的区别在于元类解决方案在Python 2.5及更早版本(低至2.2)中工作,并且元类是继承的.使用装饰器,子类必须各自单独应用装饰器(如果他们想要设置rules属性.)
两种解决方案都不考虑继承 - 它们在查找标记为规则的方法时不查看父类,也不查看父类rules
属性.如果那是你想要的,那么要扩展它们并不难.
归档时间: |
|
查看次数: |
2876 次 |
最近记录: |