[英]Python logging: Why is __init__ called twice?
我正在尝试将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"
- 为什么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的调用次数?
通常, __del__
运算符称为when-python-wants,更确切地说,是在垃圾回收器决定对对象进行垃圾回收时调用的。 这不一定是在您释放它之后。
您缺少if __name__ == "__main__":
保护您的日志记录配置代码。 当logging
导入您的test1
模块以查找类引用时,它将再次执行。
或者,在配置文件中使用名称__main__.Test1TimedRotatingFileHandler
,或者将配置代码和处理程序类放在不同的文件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.