我正在尝试使用配置文件和自己的处理程序进行python日志记录。这在某种程度上起作用。让我感到困惑的是__init__
被调用两次而__del__
被调用一次。当我删除整个配置文件并在代码__init__
内直接创建处理程序时,调用一次,__del__
永远不会被调用。
我的问题:
__init__
被调用两次?__del__
的调用频率低于__init__
?代码:
#!/bin/env python
import logging
import logging.handlers
import logging.config
class Test1TimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
def __init__(self,filename):
print "init called"
logging.handlers.TimedRotatingFileHandler.__init__(self,filename, when='S', interval=86400, backupCount=8, encoding=None)
def __del__(self):
print "del called"
if hasattr(logging.handlers.TimedRotatingFileHandler,"__del__"):
logging.handlers.TimedRotatingFileHandler.__del__(self)
logging.config.fileConfig('/root/test1.conf')
logger = logging.getLogger("test1")
配置文件:
[formatters]
keys: simple
[handlers]
keys: file
[loggers]
keys: root
[formatter_simple]
format: "%(message)s"
[handler_file]
class: test1.Test1TimedRotatingFileHandler
args: ("/root/test1.log",)
level=INFO
[logger_root]
level: INFO
handlers: file
qualname: test1
输出如下:
init called
init called
del called
使用调试器获取Sentinal建议的堆栈跟踪显示:
第一个电话:
> /root/test1.py(12)__init__()
-> print "init called"
(Pdb) where
/root/test1.py(21)<module>()
-> logging.config.fileConfig('/root/test1.conf')
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(84)fileConfig()
-> handlers = _install_handlers(cp, formatters)
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(156)_install_handlers()
-> klass = _resolve(klass)
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(94)_resolve()
-> found = __import__(used)
/root/test1.py(21)<module>()
-> logging.config.fileConfig('/root/test1.conf')
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(84)fileConfig()
-> handlers = _install_handlers(cp, formatters)
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(159)_install_handlers()
-> h = klass(*args)
> /root/test1.py(12)__init__()
-> print "init called"
(Pdb) c
init called
第二个电话:
> /root/test1.py(12)__init__()
-> print "init called"
(Pdb) w
/root/test1.py(21)<module>()
-> logging.config.fileConfig('/root/test1.conf')
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(84)fileConfig()
-> handlers = _install_handlers(cp, formatters)
/usr/local/python/2.6.4/lib/python2.6/logging/config.py(159)_install_handlers()
-> h = klass(*args)
> /root/test1.py(12)__init__()
-> print "init called"
答案 0 :(得分:12)
- 为什么init被调用两次?
醇>
如果您遵循logging
模块的代码,您将看到当您加载日志记录配置文件时,它会实例化所有处理程序(第一次实例化)。
在你的代码中,你将你的处理程序声明为test1.Test1TimedRotatingFileHandler
,所以当它尝试导入你的处理程序时,它会解析test1模块中的代码......所以它会重新创建处理程序!!
更正后的代码将使用__name__ == '__main__'
保护:
#!/bin/env python
import logging
import logging.handlers
import logging.config
class Test1TimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
def __init__(self,filename):
print "init called"
logging.handlers.TimedRotatingFileHandler.__init__(self,filename, when='S', interval=86400, backupCount=8, encoding=None)
def __del__(self):
print "del called"
if hasattr(logging.handlers.TimedRotatingFileHandler,"__del__"):
logging.handlers.TimedRotatingFileHandler.__del__(self)
if __name__ == "__main__":
logging.config.fileConfig('./test1.conf')
logger = logging.getLogger("test1")
2。为什么del比init更少被调用?
通常,在-python-want时调用__del__
运算符,更确切地说,当垃圾收集器决定垃圾收集对象时调用它;这不一定就在你发布之后。
答案 1 :(得分:5)
您在日志记录配置代码中缺少if __name__ == "__main__":
警卫。当logging
导入test1
模块以查找类引用时,它将再次执行。
或者,在配置文件中使用名称__main__.Test1TimedRotatingFileHandler
,或者将配置代码和处理程序类放在不同的文件中。