【发布时间】:2016-03-31 18:41:23
【问题描述】:
我正在与asyncio 合作,以安排以特定相对时间间隔调用的方法。我决定将调度集中到我编写的类的一种方法中,以减少项目逻辑出错的机会。
每次调度方法完成时都应调用此类方法。我虽然在每个方法的末尾添加loop.call_soon,但我决定试一试decorators。
我编写了一个类装饰器,然后将它应用到我的主类的一些方法中,编写了其余的逻辑等等。但是当试图测试我对项目的更改时,我得到了一个例外:
AttributeError: 'function' object has no attribute '__self__'
不知何故,装饰我的方法使它成为一个函数。这是我无法理解的事情,为什么会发生这种情况?如何在不放弃装饰器的情况下解决这个问题?
这是我正在尝试做的一个最小、完整且可验证的示例:
import asyncio
from datetime import datetime
class thinkagain:
loop = asyncio.get_event_loop()
def __init__(self, f):
self.fun = f
self.class_ = f.__self__
def __call__(self):
self.fun(*args, **kwords)
# everything in Python is an object
setattr(self.fun, "called", datetime.utcnow())
self.loop.call_later(self.class_.think, 5 * 60)
class DoSomething:
loop = asyncio.get_event_loop()
@thinkagain
def think(self):
attr = getattr(self.dosomething, "called")
if attr:
elapsed = attr - datetime.utcnow()
seconds = elapsed.seconds
else:
seconds = 99999
if seconds >= 20 * 60:
self.loop.call_soon(self.dosomething)
@thinkagain
def dosomething(self):
print("I did something awesome!")
loop = asyncio.get_event_loop()
something = DoSomething()
loop.call_soon(something.think)
loop.run_forever()
这是我得到的例外:
Python 3.5.1 (default, Dec 7 2015, 13:41:59)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/tmp/mcve.py", line 19, in <module>
class DoSomething:
File "/tmp/mcve.py", line 22, in DoSomething
@thinkagain
File "/tmp/mcve.py", line 10, in __init__
self.class_ = f.__self__
AttributeError: 'function' object has no attribute '__self__'
>>>
【问题讨论】:
标签: python python-3.x python-decorators