考虑这个模块:
#mymodule.py
import logging
def print_start_end(name):
"""
Decorator that creates a logger and logs the start
and the end of the function call
"""
def decorator(f):
logger = logging.getLogger(name)
def wrapper(*args, **kwargs):
logger.info("start")
res = f(*args, **kwargs)
logger.info("end")
return res
return wrapper
return decorator
@print_start_end(__name__)
def f(x):
return x
def g(y=f(3)):
return y
示例脚本:
import logging
from mymodule import f
logger = logging.getLogger("")
logger.setLevel(logging.INFO)
h = logging.StreamHandler()
h.setLevel(logging.INFO)
logger.addHandler(h)
print f(3)
输出:
start
end
3
装饰师正在工作。但现在我编写了一个脚本来使用g
而不是f
:
import logging
from mymodule import g
logger = logging.getLogger("")
logger.setLevel(logging.INFO)
h = logging.StreamHandler()
h.setLevel(logging.INFO)
logger.addHandler(h)
print g()
输出:
3
执行语句print g()
时,对f
的调用成功,因为它打印了预期的返回值3.但为什么它也不打印" start"和"结束"?
答案 0 :(得分:1)
问题是,在初始化记录器之前,会立即评估默认值。解决这个问题的方法是将执行推迟到之后。
def g(y=lambda:f(3)):
return y()
答案 1 :(得分:1)
请注意f(3)
中的def g(y=f(3)):
仅在定义函数时执行,而不是每次调用函数时都执行
因此,问题似乎是在f(3)
中执行mymodule
时,记录器尚未初始化。首先初始化,然后导入,然后它可以工作:
import logging
logger = logging.getLogger("")
logger.setLevel(logging.INFO)
h = logging.StreamHandler()
h.setLevel(logging.INFO)
logger.addHandler(h)
from mymodule import g
print g()