Python 日志记录:为什么 __init__ 被调用两次?

2024-04-11

我正在尝试将 python 日志记录与配置文件和自己的处理程序一起使用。这在某种程度上是有效的。真正让我困惑的是__init__被叫两次并且__del__被调用一次。当我删除整个配置文件内容并直接在代码中创建处理程序时__init__被调用一次并且__del__从未被调用过。

我的问题:

  1. Why is __init__叫了两次?
  2. Why is __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"

  1. 为什么 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__当-python-wants时操作符被调用,更准确地说,当垃圾收集器决定对对象进行垃圾收集时调用它;这不一定是在您释放它之后。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 日志记录:为什么 __init__ 被调用两次? 的相关文章

  • 我正在用 python 编写一个电报机器人

    我想通过Python编写一个电报机器人 但它不起作用 import telebot bot telebot TeleBot my token bot message handler content types text def sendin
  • C++ 相当于 Python getattr

    在Python中 有一个名为getattr的函数 它看起来像这样 class MyObject def init self self xyz 4 obj MyObject getattr obj xyz 其中对 getattr 的调用将返回
  • 为什么 Dash 在上传文件时会出现解析错误?

    上传 Excel 或 CSV 会导致错误 我遵循了 Dash 演示 但是当我尝试扩展它来执行绘图之类的操作时 它就不起作用了 我不想只显示一张桌子 Dash Table 函数已更新 因此之前使用 Dash Table Experiments
  • 将 KB/MB/GB 等字符串解析为数值

    为了不发明自行车 我想知道是否有任何库能够将大小字符串 MB KB TB MiB KiB 等 的各种表示形式解析为基于数字字节的值 ActiveState Receipes 有一个示例here http code activestate c
  • 使用自定义元素类在 Python 中解析 xml

    我想使用 Python 的 xml etree ElementTree 模块解析 xml 文档 但是 我希望生成的树对象中的所有元素都具有我定义的一些类方法 这建议创建我自己的 Python 元素类的子类 但我无法告诉解析器在解析时使用我自
  • 多级QTreeView

    我很难理解如何使用 QTreeView 和 QStandardItemModel 设置多级 QTree 这是我所拥有的 from PySide QtGui import import sys class MainFrame QWidget
  • 如何将 NaN 数组插入 numpy 二维数组

    我试图在二维数组中的特定位置插入任意数量的 NaN 值行 我正在将来自微控制器的一些数据记录在 csv 文件中并使用 python 进行解析 数据存储在 3 列 2D 数组中 如下所示 122 0 1 0 47 0 123 0 1 0 47
  • scipy 的 curve_fit 函数的尺寸问题

    我对 python 中的曲线拟合以及一般的 python 都很陌生 目前 我正在尝试使用 scipy 中的 curve fit 模块来拟合 4 个光谱峰 简而言之 我的文本文件中有两列数据 所以我的第一步是将数据导入到两个数组中 一个包含
  • 如何在 PyCharm 中启用 flake8 的自动代码格式化

    我使用 Tox 运行单元测试 并使用 flake8 命令检查代码格式错误 每次我在 PyCharm 中编码时 我都会运行 tox 然后意识到我有一堆烦人的格式错误 我必须返回并手动修复 我希望 PyCharm 自动格式化代码 根据 flak
  • 使用底图和Python在地图中绘制海洋

    我正在绘制此处提供的 netCDF 文件 https goo gl QyUI4J https goo gl QyUI4J Using the code below the map looks like this 然而 我希望海洋是白色的 更
  • 有没有办法在Python中调用子类定义的方法?

    The init 方法定义了创建类的实例时要执行的操作 创建子类时我可以做类似的事情吗 假设我有抽象类Entity class Entity def onsubclasscreation cls for var in cls annotat
  • Python 字符串参数解析

    我正在 python 中使用 cmd 类 它将所有参数作为一个大字符串传递给我 将此 arg 字符串标记为 args 数组的最佳方法是什么 Example args arg arg1 arg2 with quotes arg4 arg5 1
  • 让垂直网格线出现在 matplotlib 的线图中

    我想在绘图上同时获得水平和垂直网格线 但默认情况下仅显示水平网格线 我正在使用一个pandas DataFrame从 python 中的 sql 查询生成 x 轴上带有日期的线图 我不知道为什么它们没有出现在日期上 我试图寻找这个问题的答案
  • 为什么这个记忆器适用于递归函数?

    我不明白为什么下面的代码是这样的fib以线性而非指数时间运行 def memoize obj Memoization decorator from PythonDecoratorLibrary Ignores kwargs cache ob
  • 嵌套 for 循环以列出具有不同“if”条件的理解

    我正在尝试将此嵌套循环转换为列表理解 但我不确定是否可能 因为 tmp 列表中的项目可能有不同的值 这是最好的方法吗 谢谢 final for a in range 13 1 for b in range 0 4 for c in rang
  • 对二进制数的字符串表示进行按位运算 python 2.7

    我想对二进制数的两个字符串表示执行按位或 但我不知道如何将字符串转换为原始二进制 a 010110 b 100000 a b 应该产生 110110 然后我想计算 on 位的数量 这应该返回 4 您可以使用内置的将字符串转换为二进制int
  • Mac OS 上的 pybluez 安装错误

    我尝试安装pybluez使用以下命令 pip install pybluez sudo easy install pybluez 但对于这两个命令我最终都会出错 环境 Mac OSX 10 9 1 Python 2 7 点日志 cc fno
  • 帮助我在 Python 中实现反向传播

    EDIT2 新的训练集 Inputs 0 0 0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 1 0 0 0 1 0 1 0 1 0 2 0 1 0 3 0 1 0 4 0 2 0 0 0 2 0 1 0 2 0 2
  • Python 中的“lambda”是什么意思,最简单的使用方法是什么?

    您能否给出一个示例和其他示例来说明何时以及何时不使用 Lambda 我的书给了我一些例子 但它们很令人困惑 拉姆达 起源于拉姆达演算 http en wikipedia org wiki Lambda calculus和 AFAIK 首先实
  • 在大型文本文件中查找重复记录

    我在一台 Linux 机器 Redhat 上 并且有一个 11GB 的文本文件 文本文件中的每一行包含单个记录的数据 并且该行的前 n 个字符包含该记录的唯一标识符 该文件包含略多于 2700 万条记录 我需要验证文件中不存在具有相同唯一标

随机推荐