Python-类装饰器-运行时继承
我正在尝试创建一个decorator,它将向包装类Python-类装饰器-运行时继承,python,class,python-decorators,Python,Class,Python Decorators,我正在尝试创建一个decorator,它将向包装类\uuuu init\uuuu方法注入一些功能。这就是有效的方法 class Decorator: def __init__(self, arg): print(arg) self.arg = arg def __call__(self, cls): print(cls) class Wrapped(cls): def __init__(s
\uuuu init\uuuu
方法注入一些功能。这就是有效的方法
class Decorator:
def __init__(self, arg):
print(arg)
self.arg = arg
def __call__(self, cls):
print(cls)
class Wrapped(cls):
def __init__(self, first_arg, second_arg, **kwargs):
cls.__init__(self, first_arg, second_arg, **kwargs)
print('in wrapped init', self.variable)
return Wrapped
@Decorator('random_string')
class TestClass:
def __init__(self, first_arg, second_arg, **kwargs):
self.variable = 10
print('TestClass init')
test = TestClass(first_arg='one', second_arg='two')
生产
random_string
<class '__main__.TestClass'>
TestClass init
in wrapped init 10
输出:
Traceback (most recent call last):
File "/home/python_examples/test_decorators.py", line 24, in <module>
test = TestClass(first_arg='one', second_arg='two')
<class '__main__.TestClass'>
TypeError: __call__() got an unexpected keyword argument 'first_arg'
回溯(最近一次呼叫最后一次):
文件“/home/python\u examples/test\u decorators.py”,第24行,在
test=TestClass(第一个参数为一,第二个参数为二)
TypeError:\uuuuu call\uuuuuuuuu()获得意外的关键字参数“first\u arg”
两个问题:
- 这是一种众所周知且有效的装饰类方法吗
- 为什么从未使用过的“随机字符串”参数至关重要
- 这是因为您的decorator类将
arg
作为构造函数参数。因此,当您删除decorator参数时,请确保您也从\uuuu init\uuu
方法中删除了该参数。改变这个
class Decorator:
def __init__(self, arg):
print(arg)
self.arg = arg
def __call__(self, cls):
print(cls)
class Wrapped(cls):
def __init__(self, first_arg, second_arg, **kwargs):
cls.__init__(self, first_arg, second_arg, **kwargs)
print('in wrapped init', self.variable)
return Wrapped
对此
class Decorator:
def __init__(self):
pass
def __call__(self, cls):
print(cls)
class Wrapped(cls):
def __init__(self, first_arg, second_arg, **kwargs):
cls.__init__(self, first_arg, second_arg, **kwargs)
print('in wrapped init', self.variable)
return Wrapped
将解决您的问题。这是因为您的decorator类将
arg
作为构造函数参数。因此,当您删除decorator参数时,请确保您也从\uuuu init\uuu
方法中删除了该参数。改变这个
class Decorator:
def __init__(self, arg):
print(arg)
self.arg = arg
def __call__(self, cls):
print(cls)
class Wrapped(cls):
def __init__(self, first_arg, second_arg, **kwargs):
cls.__init__(self, first_arg, second_arg, **kwargs)
print('in wrapped init', self.variable)
return Wrapped
对此
class Decorator:
def __init__(self):
pass
def __call__(self, cls):
print(cls)
class Wrapped(cls):
def __init__(self, first_arg, second_arg, **kwargs):
cls.__init__(self, first_arg, second_arg, **kwargs)
print('in wrapped init', self.variable)
return Wrapped
将解决您的问题。实际上,它是这样工作的:
# Assume you have a decorator class and a class named A which is needed to decorate.
@Decorator
class A:
...
# is the same as
class A:
...
A = Decorator()(A)
这就是为什么您需要定义\uuuuu-cal\uuuu
在这里您可以看到,如果您的装饰程序
接受一些参数进行初始化,您需要使用类似A=Decorator(xxx)(A)
的东西。而decorator语法中的等效项是:
@Decorator(xxx)
class A:
...
实际上,这就是它的工作原理:
# Assume you have a decorator class and a class named A which is needed to decorate.
@Decorator
class A:
...
# is the same as
class A:
...
A = Decorator()(A)
这就是为什么您需要定义\uuuuu-cal\uuuu
在这里您可以看到,如果您的装饰程序
接受一些参数进行初始化,您需要使用类似A=Decorator(xxx)(A)
的东西。而decorator语法中的等效项是:
@Decorator(xxx)
class A:
...
它不起作用。回溯(最后一次调用):文件“/home/python\u examples/test\u decorators.py”,第16行,在@Decorator TypeError:\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()接受1个位置参数,但有2个位置参数。像这样调用Decorator
而不是像这样调用Decorator这两种?在使用@annotation时,我从不需要实例化decorator。我的意思是,使用@like@decorator()
调用decorator。如果是函数,则无需添加括号。因为它是一个类,我们需要添加括号。所谓“因为它是一个类,我们需要添加括号”,你是指装饰器本身还是它装饰的类(在本例中为TestClass)?它不起作用。回溯(最后一次调用):文件“/home/python\u examples/test\u decorators.py”,第16行,在@Decorator TypeError:\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()接受1个位置参数,但有2个位置参数。像这样调用Decorator而不是像这样调用Decorator这两种?在使用@annotation时,我从不需要实例化decorator。我的意思是,使用@like@decorator()
调用decorator。如果是函数,则无需添加括号。因为它是一个类,所以我们需要添加括号。这里的“因为它是一个类,所以我们需要添加括号”是指装饰器本身还是它装饰的类(在本例中为TestClass)?