如何从孩子的基类访问装饰器?
我(错误地)假设了ffg。会工作:
class baseclass(object):
def __init__(self):
print 'hey this is the base'
def _deco(func):
def wrapper(*arg):
res = func(*arg)
print 'I\'m a decorator. This is fabulous, but that colour, so last season sweetiedarling'
return res
return wrapper
@_deco
def basefunc(self):
print 'I\'m a base function'
这个类工作正常,但后来我创建了一个继承自此类的子类:
class otherclass(baseclass):
def __init__(self):
super(otherclass, self).__init__()
print 'other class'
@_deco
def meh(self):
print 'I\'m a function'
这甚至不能正确导入,更不用说运行了。 @_deco未定义。尝试baseclass._deco抛出一个未绑定的方法_deco()错误,这并不奇怪。
任何想法如何做到这一点,我真的很想将装饰器封装在课堂上,但我并没有嫁给这个想法,我需要在基础上调用它。孩子班。
答案 0 :(得分:9)
class baseclass(object):
def __init__(self):
print 'hey this is the base'
def _deco(func):
def wrapper(*arg):
res = func(*arg)
print 'I\'m a decorator. This is fabulous, but that colour, so last season sweetiedarling'
return res
return wrapper
@_deco
def basefunc(self):
print 'I\'m a base function'
@_deco
def basefunc2(self):
print "I'm another base function"
#no more uses of _deco in this class
_deco = staticmethod(_deco)
# this is the key. it must be executed after all of the uses of _deco in
# the base class. this way _deco is some sort weird internal function that
# can be called from within the class namespace while said namespace is being
# created and a proper static method for subclasses or external callers.
class otherclass(baseclass):
def __init__(self):
super(otherclass, self).__init__()
print 'other class'
@baseclass._deco
def meh(self):
print 'I\'m a function'
答案 1 :(得分:0)
也有python3特定的方式在子类中使用该装饰器,而没有提及父级,这完全符合OP的建议。它要求装饰器必须使用其here方法在父级的元类中实现装饰符(可以在__prepare__()中找到对元分类的很好的解释)。
aaronasterling's answer是解决该问题的有效且首选的方式,我仅将其发布为一个有趣的示例,以帮助其他人理解语言的基础。仅在没有其他方法可以满足您的需求时才使用元类!
class metaclass(type):
@classmethod
def __prepare__(metacls, name, bases):
def _deco(func):
def wrapper(*arg):
res = func(*arg)
print('I\'m a decorator. This is fabulous, but that colour, so last season sweetiedarling')
return res
return wrapper
return {"_deco": _deco}
class baseclass(metaclass=metaclass):
def __init__(self):
print('hey this is the base')
@_deco
def basefunc(self):
print('I\'m a base function')
class otherclass(baseclass):
def __init__(self):
super(otherclass, self).__init__()
print('other class')
@_deco
def meh(self):
print('I\'m a function')
示例代码在python3中运行良好:
>>> obj = otherclass()
hey this is the base
other class
>>> obj.meh()
I'm a function
I'm a decorator. This is fabulous, but that colour, so last season sweetiedarling
关于__prepare __()方法的重要说明:
dict
)