我有一个带参数的装饰器。
def decorator(abc):
def inner(func):
def wrapper(*args, **kwargs):
print(abc) # prints base class variable
# do something
return True
return wrapper
return inner
我有如下的儿童家长班:-
class ABC():
abc = 1
@decorator(abc)
def func(self):
return True
class DEF(ABC):
abc = 2
obj = DEF()
print(obj.func())
我面临的问题是在将子类变量传递给装饰器时,它仍然需要基类变量。
如何将子类变量传递给装饰器?
答案 0 :(得分:1)
在基类及其功能的定义时,将向您的装饰器传递一个具体值。没有任何属性访问,并且该函数也不会在派生类中进行神奇的重新定义和新值重新装修。 首先,将类属性传递给方法装饰器也没有多大意义,因为该方法无论如何都可以通过传递的实例动态访问它。您可以做的简单得多:
def decorator(func):
def inner(self, *args, **kwargs):
print(self.__class__.abc) # actually prints the class attribute
# do something
return True
return inner
class ABC(object):
abc = 1
@decorator
def func(self):
return True
>>> a = ABC()
>>> a.func()
1
True
>>> b = DEF()
>>> b.func()
2
True
答案 1 :(得分:0)
另一种解决方案可能是重写DEF中的方法,因为根据DEF .__ mro__,由于python无法找到DEF中声明的方法,它将进入父类并在那里找到它,并传入ABC的class属性。 / p>
DEF .__ mro__的输出:
(__main__.DEF, __main__.ABC, object)
建议的解决方案:
class ABC(object):
abc = 1
@decorator(abc)
def func(self):
return True
class DEF(ABC):
abc = 2
@decorator(abc)
def func(self):
return True
答案 2 :(得分:0)
一种简单的方法是考虑要在装饰器中处理的是属性的运行时值。然后,您只需传递属性名称并在运行时使用它即可。足够了,因为方法将其对象作为其第一个参数:
array(2) {
["type"]=> string(9) "ByteArray"
["value"]=> string(40) "0631901fb121f633fa496d3689649a06628f63c8"
}
给出预期的结果:
def decorator(attr):
def inner(func):
def wrapper(*args, **kwargs):
print(getattr(args[0], attr)) # prints current attribute
# do something
return True
return wrapper
return inner
class ABC():
abc = 1
@decorator('abc')
def func(self):
return True
class DEF(ABC):
abc = 2
obj = DEF()
obj.func()