[英]Decorating Python class methods - how do I pass the instance to the decorator?
[英]In a decorator how can I pass the function I'm decorating as an argument?
我做了這個簡單的裝飾器,基本上將裝飾的功能放在try...except
。
from functools import wraps
def try_except(on_exception=None, exception=Exception, *args, **kwargs):
from sys import stderr
def decorator(func):
@wraps(func)
def wrapper(*args1, **kwargs1):
try:
return func(*args1, **kwargs1)
except exception as e:
print(repr(e), file=stderr)
if on_exception is not None:
return on_exception(*args, **kwargs)
return wrapper
return decorator
然后,我嘗試裝飾以下函數,因此如果引發ValueError
,它將調用自身:
@try_except(get_int, ValueError, "Please enter a valid integer!\n>>> ")
def get_int(prompt=">>> "):
return int(input(prompt))
但是我收到以下錯誤:
Traceback (most recent call last):
File "C:\Python\decorator_test.py", line 9348234, in <module>
@try_except(get_int, ValueError, "Please enter a valid integer!\n>>> ")
NameError: name 'get_int' is not defined
我知道我可以使用try...except
將它放在while
循環中,但函數中try...except
,但這是我的一項學習練習。 有什么辦法可以避免這種情況的發生?
修復此問題的最佳方法是使用調用該函數的函數。
def _get_int(prompt):
get_int(prompt)
@try_except(_get_int, ValueError, "Please enter a valid integer!\n>>> ")
def get_int(prompt=">>> "):
return int(input(prompt))
del _get_int
# Or even a lambda
@try_except(lambda p: get_int(p), ValueError, "Please enter a valid integer!\n>>> ")
def get_int(prompt=">>> "):
return int(input(prompt))
由於_get_int
返回什么get_int
在呼叫的時間(即運行時)返回時,它會改變什么get_int
目前。
您可能認為您可以在沒有@
語法糖的情況下完成此操作,但這只會調用先前的(未裝飾的)函數,因此不會遞歸。
一種方法是定義並使用哨兵對象表示“調用正在執行的相同修飾函數。即,在def try_except
之前,添加:
same = object()
在包裝的正文中,在try
/ except
:
if on_exception is not None:
if on_exception is same:
return decorator(func)(*args, **kwargs)
else:
return on_exception(*args, **kwargs)
然后,裝飾的函數將是(例如,Python 3,我想,考慮到您使用input
的方式-無疑在Python 2中將是raw_input
)...:
@try_except(same, ValueError, "Please enter a valid integer!\n>>> ")
def get_int(prompt=">>> "):
return int(input(prompt))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.