我有一个小的日志记录包装器模块test.logging
:
import logging
debuglog = "debug.log"
f = open(debuglog, 'w') # truncate the file
f.close()
logger = logging.getLogger('test')
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s %(name)s %(levelname)s: %(filename)s:%(lineno)d: %(message)s')
fh = logging.FileHandler(debuglog)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger.addHandler(fh)
def get(moduleName):
return logging.getLogger("test." + moduleName)
以及一些使用它的模块,例如test.example
:
import test.logging
logger = test.logging.get(__name__)
logger.info("This is an info message from test.example")
我想知道是否有一种方法可以减少出现在的每个子模块中的前两行的重复test
。我想做类似的事情:
from test.logging get(__name__) as logger
logger.info("This is an info message from test.example")
甚至更好,如果我也可以省略__name__
并get()
自动确定模块名称。(从我收集的数据来看,这对于inspect
模块来说是可能的,但是如果装饰了调用方或将程序编译为EXE,则可能不正确。)
这样的事情可能吗?
就我个人而言,我会坚持使用您拥有的代码;更少的魔术,更多的清晰度。
您可以使用以下方法通过访问堆栈中的框架来访问调用代码的模块名称sys._getframe()
:
import sys
def get(moduleName=None):
if moduleName is None:
caller = sys._getframe(1)
moduleName = caller.f_globals['__name__']
return logging.getLogger("test." + moduleName)
使模块名称为可选:
from test import logging
logger = logging.get()
是的,如果您的调用logging.get()
是在装饰器函数内部,那么从理论上讲,您可以访问另一组全局变量(装饰器在其中定义的那些模块),但是在大多数情况下,这恰好是模块名, d要使用。通过将其设置为moduleName
可选,您保留了针对极端情况明确设置它的可能性。
将Python程序打包到可执行文件(具有py2exe
或相似的可执行文件)可能会影响文件名(尤其是对于主脚本),但是模块名称应保持不变。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句