如何在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()
来获取参数。不仅如此