Python 我如何在类中定义装饰器方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13852138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how can i define decorator method inside class?
提问by Max
Possible Duplicate:
Can a class method be a decorator?
可能的重复:
类方法可以是装饰器吗?
here's an example.
这是一个例子。
class myclass:
def __init__(self):
self.start = False
def check(self):
return not self.start
def doA(self):
if self.check():
return
print('A')
def doB(self):
if self.check():
return
print('B')
as you see,i want to write the check action in a decorator way, but after i tried many times, i found i can only write the method outside my class.please teach me how to write it inside the class ,thanks
如您所见,我想以装饰器的方式编写检查操作,但是经过多次尝试后,我发现我只能在类外编写该方法。请教我如何在类内编写它,谢谢
edit:
编辑:
i can write the code in this way:
我可以这样写代码:
def check(func):
def checked(self):
if not self.start:
return
func(self)
return checked
class myclass:
def __init__(self):
self.start = False
@check
def doA(self):
print('A')
@check
def doB(self):
print('B')
a = myclass()
a.doA()
a.doB()
a.start = True
a.doA()
a.doB()
but i don't think it's a good practice, i want to defined the check method inside my class.
但我认为这不是一个好习惯,我想在我的班级中定义 check 方法。
回答by jdi
While I don't think this is completely needed all the time, here is how you would make a decorator within your class. It is a little more cumbersome because of the way the methods become bound to the selflater on. Normally with plain function decorators you don't have to worry about that.
虽然我不认为这一直是完全需要的,但这里是您在类中制作装饰器的方法。由于方法绑定到self后者的方式,它有点麻烦。通常使用普通的函数装饰器你不必担心。
The requirements are:
要求是:
- The decorator needs to be defined first before the methods that will use it
- It needs to use
functools.wrapto preserve the bound methods properly
- 装饰器需要在使用它的方法之前先定义
- 它需要用来
functools.wrap正确保存绑定的方法
Example:
例子:
from functools import wraps
class myclass:
def __init__(self):
self.start = False
def _with_check(f):
@wraps(f)
def wrapped(inst, *args, **kwargs):
if inst.check():
return
return f(inst, *args, **kwargs)
return wrapped
def check(self):
return self.start
@_with_check
def doA(self):
print('A')
@_with_check
def doB(self):
print('B')
I made it a protected member since it is not really something someone else needs to use outside of the class. And it still preserves your public check()call for use by itself. The decorator simply wraps calling it first before calling the target method.
我将它设为受保护成员,因为它并不是其他人需要在课堂之外使用的东西。并且它仍然保留您的公开check()呼叫以供自己使用。装饰器简单地在调用目标方法之前先调用它。
回答by Silas Ray
If you have a need to modify how many or all methods on a class are called, but you only want to apply that change in behavior to that class and its subclasses, just use __getattr__()and/or __getattribute__()to perform your behavior instead.
如果您需要修改某个类上调用的方法数量或所有方法,但您只想将该行为更改应用于该类及其子类,只需使用__getattr__()和/或__getattribute__()执行您的行为即可。

