我试图根据函数范围内logging.Logger
实例的相应方法生成一堆函数。我感兴趣的功能/方法是:
['debug', 'info', 'warning', 'error', 'critical', 'exception']
所有人都拥有相同的原型。
现在我可以明确说明:
global debug, info, warning, error critical, exception
然后继续def
每个人。我查了一下,这很好用。问题是我必须重复自己。
所以我有一个logging.Logger
名为mylog
的实例,它已经是全球性的。以下是我想要的,但分别通过硬编码函数/方法的名称:
global debug
def debug(msg, *args, **kwargs):
if mylog: mylog.debug(msg, *args, **kwargs)
为了简洁起见,我将编写我的示例,只考虑debug
,跳过其余部分。不幸的是,真正的代码有点复杂,因此使用lambda
的要求似乎得以实现(单一陈述,对吧?)。
所以我明显的想法是在getattr
上使用名称为"debug"
的{{1}},并简单地调用我在已定义函数中返回的内容,并将其按名称添加到mylog
1}} globals()
。例如:
dict
但是我认为这实际上并不合法,因为我称这是一个类方法,就像它是一个静态方法一样。然而,这"起作用",但每个输出行后跟另一行说for fct in ['debug']:
def x(msg, *args, **kwargs):
if mylog: getattr(mylog, fct)(msg, *args, **kwargs)
globals()[fct] = x
。
所以我想我可以将实例作为第一个参数传递。完成None
之后的所有内容:
self
给了我:
for fct in ['debug']:
def x(msg, *args, **kwargs):
if mylog: getattr(mylog, fct)(mylog, msg, *args, **kwargs)
globals()[fct] = x
这与我从中获得的效果相同:
TypeError: not all arguments converted during string formatting
我根据这个问题的接受答案:Dynamically bind method to class instance in python
应用Alex Martelli here的答案会产生同样的错误。
我做错了什么?如何在不重复自己的情况下实现理想的行为?
完整追溯:
for fct in ['debug']:
import types
def x(msg, *args, **kwargs):
if mylog: types.MethodType(getattr(mylog, fct), mylog)(msg, *args, **kwargs)
globals()[fct] = x
完整脚本,基于上面的第一个示例代码:
Traceback (most recent call last):
File "/usr/lib64/python2.6/logging/__init__.py", line 776, in emit
msg = self.format(record)
File "/usr/lib64/python2.6/logging/__init__.py", line 654, in format
return fmt.format(record)
File "/usr/lib64/python2.6/logging/__init__.py", line 436, in format
record.message = record.getMessage()
File "/usr/lib64/python2.6/logging/__init__.py", line 306, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
答案 0 :(得分:1)
在我看来,这应该有效:
debug = mylog.debug
或:
debug, info, warning, error, critical, exception = (
mylog.debug, mylog.info, mylog.warning,
mylog.error, mylog.critical, mylog.exception)
动态设置:
for fct in ('debug', 'info', 'warning'):
globals()[fct] = getattr(mylog, fct)
您的for循环for fct in ('debug'):
正在遍历字符串'debug'
,您需要一个逗号for fct in ('debug',):
才能使其成为元组。
还要注意构造如:
for fct in ['debug']:
def x(msg, *args, **kwargs):
if mylog: getattr(mylog, fct)(msg, *args, **kwargs)
globals()[fct] = x
定义函数在调用时使用`fct``的当前值。您需要额外的间接级别来处理多个日志记录方法。 e.g。
def make_log(fct):
def x(msg, *args, **kwargs):
if mylog: getattr(mylog, fct)(msg, *args, **kwargs)
return x
for fct in ['debug','info']:
globals()[fct] = make_log(fct)