如何 "decorate" 调用站点中的函数而不是定义
How to "decorate" a function in the call site rather than definition
我在处理异常的有用内省助手,因此想概括代码而不是一直复制粘贴它。我有
def state_on_exc(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
result = f(*args, **kwargs)
return result
except Exception as e:
ex_type, exc_value, tb = sys.exc_info()
if tb is not None:
prev = tb
curr = tb.tb_next
while curr is not None:
prev = curr
curr = curr.tb_next
print(prev.tb_frame.f_locals)
raise e
@state_on_exc
def apply(f):
return f
def myfunc():
a = 5
raise ValueError
apply(myfunc())
但是包装器似乎没有在异常时调用(它专门在 myfunc()
中引发)- 它不打印任何局部变量。有没有什么合适的方法可以达到同样的效果,或者有更好的方法吗?
非常接近。
- 您需要 return 装饰器中的包装函数。
- 要重新引发,您不应将异常对象添加到引发 stmt。
- 要装饰函数,将函数对象传递给装饰器函数。
- 调用修饰函数,调用修饰函数。而不是非修饰函数。
示例:
from functools import wraps
def decorate(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
# handle exception
print("handled exception:", type(e))
# re-raise
raise
return wrapper
def myfunc():
a = 5
raise ValueError
decorated_fun = decorate(myfunc)
decorated_fun()
输出为:
$ python3 test.py
handled exception: <class 'ValueError'>
Traceback (most recent call last):
File "tt.py", line 25, in <module>
decorated_fun()
File "tt.py", line 7, in wrapper
result = f(*args, **kwargs)
File "tt.py", line 22, in myfunc
raise ValueError
ValueError
我在处理异常的有用内省助手,因此想概括代码而不是一直复制粘贴它。我有
def state_on_exc(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
result = f(*args, **kwargs)
return result
except Exception as e:
ex_type, exc_value, tb = sys.exc_info()
if tb is not None:
prev = tb
curr = tb.tb_next
while curr is not None:
prev = curr
curr = curr.tb_next
print(prev.tb_frame.f_locals)
raise e
@state_on_exc
def apply(f):
return f
def myfunc():
a = 5
raise ValueError
apply(myfunc())
但是包装器似乎没有在异常时调用(它专门在 myfunc()
中引发)- 它不打印任何局部变量。有没有什么合适的方法可以达到同样的效果,或者有更好的方法吗?
非常接近。
- 您需要 return 装饰器中的包装函数。
- 要重新引发,您不应将异常对象添加到引发 stmt。
- 要装饰函数,将函数对象传递给装饰器函数。
- 调用修饰函数,调用修饰函数。而不是非修饰函数。
示例:
from functools import wraps
def decorate(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
# handle exception
print("handled exception:", type(e))
# re-raise
raise
return wrapper
def myfunc():
a = 5
raise ValueError
decorated_fun = decorate(myfunc)
decorated_fun()
输出为:
$ python3 test.py
handled exception: <class 'ValueError'>
Traceback (most recent call last):
File "tt.py", line 25, in <module>
decorated_fun()
File "tt.py", line 7, in wrapper
result = f(*args, **kwargs)
File "tt.py", line 22, in myfunc
raise ValueError
ValueError