M. *_* R. 4 python python-decorators
我试图在我的类中创建一个方法来计算特定函数的完整运行。我想使用一个简单的装饰器。我找到了这个参考并重写了这个简单的脚本:
class myclass:
def __init__(self):
self.cnt = 0
def counter(function):
"""
this method counts the runtime of a function
"""
def wrapper(self, **args):
function(**args)
self.counter += 1
return wrapper
@myclass.counter
def somefunc():
print("hello from somefunc")
if __name__ == "__main__":
obj = myclass()
# or if comment @myclass.counter
# somefunc = myclass.counter(somefunc)
somefunc()
Run Code Online (Sandbox Code Playgroud)
当然,我得到:
TypeError: wrapper() missing 1 required positional argument: 'self'
Run Code Online (Sandbox Code Playgroud)
我尝试将计数器重写为类方法:
class myclass:
def __init__(self):
self.cnt = 0
def counter(self, function):
"""
this method counts the runtime of a function
"""
def wrapper(**args):
function(**args)
self.cnt += 1
return wrapper
def somefunc():
print("hello from somefunc")
if __name__ == "__main__":
obj = myclass()
somefunc = obj.counter(somefunc)
for i in range(10):
somefunc()
print(obj.cnt)
Run Code Online (Sandbox Code Playgroud)
效果很好,但我认为这不是一个有效的装饰器定义。有什么方法可以在类方法中定义装饰器并将自参数传递给其函数吗?或者在类中定义装饰器是没有用的?
编辑:------ 首先,我无法在类方法之外定义装饰。其次,我试图创建一个预定的类,该类在固定的时间间隔和特定的时间内运行特定的函数(作为输入),因此我需要对其进行计数。
所以我可以为你起草一些东西,下面是代码:
def count(func):
def wrapper(self):
TestClass.call_count += 1
func(self)
return wrapper
class TestClass(object):
call_count = 0
@count
def hello(self):
return 'hello'
if __name__ == '__main__':
x = TestClass()
for i in range(10):
x.hello()
print(TestClass.call_count)
Run Code Online (Sandbox Code Playgroud)
为什么在类中使用装饰器会导致问题:
decorator function在课堂上建立一个内部并不是一件容易的事。原因如下:
原因 1
每个类方法都必须采用一个参数,self该参数instance是调用该函数的类的参数。现在,如果您让装饰器函数接受self参数,则装饰器调用@count将失败,因为它会转换为count()不传递self参数的函数,从而出现错误:
类型错误:wrapper() 缺少 1 个必需的位置参数:“self”
原因 2
现在为了避免这种情况,您可以decorator通过更改声明来使您的静态化,如下所示:
@staticmethod
def count(func):
pass
Run Code Online (Sandbox Code Playgroud)
但随后你又遇到了另一个错误:
类型错误:“静态方法”对象不可调用
这意味着您也不能拥有静态方法。如果类中不能有静态方法,则必须将self实例传递给该方法,但如果将self实例传递给它,@count装饰器调用将不会传递该self实例,因此它将不起作用。
因此,这里有一个博客很好地解释了它、与之相关的问题以及替代方案。
我个人更喜欢使用 a 来helper class保存所有decorators可以使用的类,而不是定义它的唯一类。这将使您能够灵活地重用装饰器,而不是重新定义它们,这将遵循意识形态
编写一次代码,一遍又一遍地重复使用。
| 归档时间: |
|
| 查看次数: |
8528 次 |
| 最近记录: |