如何在Python中以可重用的方式记录函数参数?
我发现自己已经多次编写过这样的代码:如何在Python中以可重用的方式记录函数参数?,python,function,logging,arguments,Python,Function,Logging,Arguments,我发现自己已经多次编写过这样的代码: def my_func(a, b, *args, **kwargs): saved_args = locals() # Learned about this from http://stackoverflow.com/a/3137022/2829764 local_var = "This is some other local var that I don't want to log" try: a/b exc
def my_func(a, b, *args, **kwargs):
saved_args = locals() # Learned about this from http://stackoverflow.com/a/3137022/2829764
local_var = "This is some other local var that I don't want to log"
try:
a/b
except Exception as e:
logging.exception("Oh no! My args were: " + str(saved_args))
raise
运行my_func(1,0,“spam”,“ham”,my_kwarg=“eggs”)
在stderr上给出以下输出:
ERROR:root:Oh no! My args were: {'a': 1, 'args': (u'spam', u'ham'), 'b': 0, 'kwargs': {'my_kwarg': u'eggs'}}
Traceback (most recent call last):
File "/Users/kuzzooroo/Desktop/question.py", line 17, in my_func
a/b
ZeroDivisionError: division by zero
我的问题是,我可以写一些可重用的东西,这样我就不必在函数顶部保存locals()?这能用一种很好的蟒蛇式的方式来完成吗
编辑:响应@mtik00的另一个请求:理想情况下,我希望从我的函数中访问保存的参数或类似内容,这样我就可以做一些事情,而不是记录未捕获的异常(也许我想在我的函数中捕获异常,记录错误,然后继续进行)。装饰程序是您要寻找的。下面是一个例子:
import logging
from functools import wraps
def arg_logger(func):
@wraps(func)
def new_func(*args, **kwargs):
saved_args = locals()
try:
return func(*args, **kwargs)
except:
logging.exception("Oh no! My args were: " + str(saved_args))
raise
return new_func
@arg_logger
def func(arg1, arg2):
return 1 / 0
if __name__ == '__main__':
func(1, 2)
这里,我使用arg_logger()作为装饰器。将decorator应用于任何希望具有此新行为的函数
关于装饰师有一个很好的讨论。装饰师是您需要的。下面是一个例子:
import logging
from functools import wraps
def arg_logger(func):
@wraps(func)
def new_func(*args, **kwargs):
saved_args = locals()
try:
return func(*args, **kwargs)
except:
logging.exception("Oh no! My args were: " + str(saved_args))
raise
return new_func
@arg_logger
def func(arg1, arg2):
return 1 / 0
if __name__ == '__main__':
func(1, 2)
这里,我使用arg_logger()作为装饰器。将decorator应用于任何希望具有此新行为的函数
关于装饰师有一个很好的讨论。装饰师是您需要的。下面是一个例子:
import logging
from functools import wraps
def arg_logger(func):
@wraps(func)
def new_func(*args, **kwargs):
saved_args = locals()
try:
return func(*args, **kwargs)
except:
logging.exception("Oh no! My args were: " + str(saved_args))
raise
return new_func
@arg_logger
def func(arg1, arg2):
return 1 / 0
if __name__ == '__main__':
func(1, 2)
这里,我使用arg_logger()作为装饰器。将decorator应用于任何希望具有此新行为的函数
关于装饰师有一个很好的讨论。装饰师是您需要的。下面是一个例子:
import logging
from functools import wraps
def arg_logger(func):
@wraps(func)
def new_func(*args, **kwargs):
saved_args = locals()
try:
return func(*args, **kwargs)
except:
logging.exception("Oh no! My args were: " + str(saved_args))
raise
return new_func
@arg_logger
def func(arg1, arg2):
return 1 / 0
if __name__ == '__main__':
func(1, 2)
这里,我使用arg_logger()作为装饰器。将decorator应用于任何希望具有此新行为的函数
关于decorators有一个很好的讨论。你只想
raise
,而不是raise e
,来保留回溯。我相信saved\u args=locals()
应该放在new\u func
的内部arg\u logger()
只会收到一个参数,因此,您应该删除那里的args
和kwargs
。正如anon所指出的,您需要将参数保存在包装函数中。实际上,save_args
是否在def new_func
的内部或外部并不重要,但将其放在那里似乎更符合逻辑,谢谢@斯文:关于装饰师的*args,**kwargs
的电话打得很好。谢谢@mtik00。当我通过类似于def func(arg1、arg2、kw_with_default='spam')的方式向func添加带有默认值的kw args时,
则“spam”(带有默认值的kw_的默认值)不会出现在输出中,这与问题中的代码不同。“垃圾邮件”可以显示在输出中吗?你只需要raise
,而不是raise e
,来保留回溯。我相信saved\u args=locals()
应该放在new\u func
的内部arg\u logger()
只会收到一个参数,因此,您应该删除那里的args
和kwargs
。正如anon所指出的,您需要将参数保存在包装函数中。实际上,save_args
是否在def new_func
的内部或外部并不重要,但将其放在那里似乎更符合逻辑,谢谢@斯文:关于装饰师的*args,**kwargs
的电话打得很好。谢谢@mtik00。当我通过类似于def func(arg1、arg2、kw_with_default='spam')的方式向func添加带有默认值的kw args时,
则“spam”(带有默认值的kw_的默认值)不会出现在输出中,这与问题中的代码不同。“垃圾邮件”可以显示在输出中吗?你只需要raise
,而不是raise e
,来保留回溯。我相信saved\u args=locals()
应该放在new\u func
的内部arg\u logger()
只会收到一个参数,因此,您应该删除那里的args
和kwargs
。正如anon所指出的,您需要将参数保存在包装函数中。实际上,save_args
是否在def new_func
的内部或外部并不重要,但将其放在那里似乎更符合逻辑,谢谢@斯文:关于装饰师的*args,**kwargs
的电话打得很好。谢谢@mtik00。当我通过类似于def func(arg1、arg2、kw_with_default='spam')的方式向func添加带有默认值的kw args时,
则“spam”(带有默认值的kw_的默认值)不会出现在输出中,这与问题中的代码不同。“垃圾邮件”可以显示在输出中吗?你只需要raise
,而不是raise e
,来保留回溯。我相信saved\u args=locals()
应该放在new\u func
的内部arg\u logger()
只会收到一个参数,因此,您应该删除那里的args
和kwargs
。正如anon所指出的,您需要将参数保存在包装函数中。实际上,save_args
是否在def new_func
的内部或外部并不重要,但将其放在那里似乎更符合逻辑,谢谢@斯文:关于装饰师的*args,**kwargs
的电话打得很好。谢谢@mtik00。当我通过类似于def func(arg1、arg2、kw_with_default='spam')的方式向func添加带有默认值的kw args时,
则“spam”(带有默认值的kw_的默认值)不会出现在输出中,这与问题中的代码不同。“垃圾邮件”可以显示在输出中吗?真的,真的不要使用locals()
获取参数。这不仅几乎不可能阅读,而且也不能保证有效。Python实现可以随时在locals
中丢弃它们想要的任何内容。实际上,确实不要使用locals()
来获取参数。这不仅几乎不可能阅读,而且也不能保证有效。Python实现可以随时在locals
中丢弃它们想要的任何内容。实际上,确实不要使用locals()
来获取参数。不仅如此