使用装饰函数作为函数的默认参数
Using a decorated function as a function's default argument
考虑这个模块:
#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
的调用是成功的,因为它打印了预期的return值3。但是为什么它不也打印"start" 和 "end"?
问题是默认值被立即评估,在记录器被初始化之前。解决这个问题的方法是将执行推迟到之后。
def g(y=lambda:f(3)):
return y()
注意def g(y=f(3)):
中的f(3)
在定义函数的时候只执行一次,不是每次调用的时候都执行
因此,问题似乎是在 mymodule
中执行 f(3)
时,记录器尚未初始化。先初始化,再导入,即可运行:
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()
考虑这个模块:
#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
的调用是成功的,因为它打印了预期的return值3。但是为什么它不也打印"start" 和 "end"?
问题是默认值被立即评估,在记录器被初始化之前。解决这个问题的方法是将执行推迟到之后。
def g(y=lambda:f(3)):
return y()
注意def g(y=f(3)):
中的f(3)
在定义函数的时候只执行一次,不是每次调用的时候都执行
因此,问题似乎是在 mymodule
中执行 f(3)
时,记录器尚未初始化。先初始化,再导入,即可运行:
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()