來自此post。接受的答案很好地與裝飾者沒有任何爭論。我試圖擴展這個解決方案,使它爲應用裝飾器帶來參數。編寫一個裝飾器,以便爲類的所有方法應用另一個裝飾器參數
詳細地說,我有使外部API調用的功能。由於這些調用經常失敗,我將此library的重試裝飾器應用於所有功能。爲了避免所有函數一次又一次地使用@retry(...)
行,我決定將它們集中到一個類中。我創建了RetryClass,並將所有功能都作爲classmethod
放入課程中。現在,我正在尋找一種方法來爲類的所有方法應用retry
裝飾器,這樣我就可以不斷在類中添加新方法,並且會自動將新修飾器應用於新方法。
注意:重試裝飾器需要參數。
@retry(wait_random_min=100, wait_random_max=300, stop_max_attempt_number=3)
這裏是我的代碼:
from retrying import retry
def for_all_methods(decorator):
def decorate(cls):
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
setattr(cls, attr, decorator(getattr(cls, attr)))
return cls
return decorate
@for_all_methods(retry(wait_random_min=100, wait_random_max=300, stop_max_attempt_number=3))
class RetryClass(object):
@classmethod
def a(cls):
pass
def test():
RetryClass.a()
return
這引發以下錯誤:
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1596, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 974, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Users/gyoho/Datatron/Dev/class-decorator/main.py", line 26, in <module>
test()
File "/Users/gyoho/Datatron/Dev/class-decorator/main.py", line 22, in test
RetryClass.a()
TypeError: unbound method a() must be called with RetryClass instance as first argument (got nothing instead)
然而,註釋掉類的裝飾,沒有錯誤運行。有什麼我失蹤?
當你想將它應用到所有的方法,你可以用[元類更好](https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python#6581949)。 – mdh