如何解决日志实例化的 Python 求值顺序为什么导入的模块首先被评估?
嗨,我有一个高级问题。我基本上很难理解为什么下游类首先实例化了一个类属性日志对象。我有一个包含大约 20 个类和 3 个不同模块的 python 应用程序,该应用程序执行一些日志记录。我想让日志路径可以从 cli 配置,但首先,我只是硬编码了日志路径并实例化了一个日志对象。然后使用硬编码路径将该日志实例记录到应用程序的所有其他部分。所以我一开始硬编码了日志路径(只是app.log
)。现在我试图允许用户设置日志记录的路径。所以在我的 Log
类中,我有一个单例式方法 set_handler
来设置处理程序,它是一个类变量。它遵循单例模式,因为它只能设置一次。因此,用户还将为“第一个”处理程序传入一个日志记录路径。如果已经为以后的日志实例设置了处理程序,则不配置处理程序,使用相同的处理程序,只返回一个新的日志对象。因此,如果用户传入 xyz.log
,那么它将被永久设置,很好。但似乎我无法确定 第一次 何时实际调用它。入口点与第一次实例化日志对象时有很大不同。我试图强制日志实例化,但 python 一直将第一个实例化为不同的东西。它实际上是一个由导入类导入的类,该类由我实际想要首先执行的类导入。并且那个类(代码直到很久以后才出现)有一个日志对象,它首先被实例化。所以那个类的日志对象正在被实例化,但用户提供的日志路径还没有被传递,这是我的意图。所以基本上我无法强制 python 首先评估正确的日志实例。
解决方法
所以发生的事情基本上就在这里,一旦导入了类属性的类,日志对象就会被评估。 (当 Class2
被导入时,它的类属性 log
被评估并因此被实例化)。这家伙写了一篇关于它的博客 - https://chase-seibert.github.io/blog/2012/01/20/python-class-attributes-are-evaluated-on-declaration.html。所以为了更详细地展示它,我有一个像
import other_stuff
from module2 import Class2
class Class1:
def __init__(self):
do stuff
def func1():
do stuff with Class2
然后在模块 2 中它看起来像
import os
import subprocess
import other_stuff
class Class2:
log = LoggerClass(log_path=__name__)
def __init__(self):
def func2():
do stuff
在应用程序入口点就是这样。这是我想先评估的部分……但它没有先评估。
import click
import other_stuff
from module1 import Class1
@click.command("start")
@click.option(--logpath)
def start(logpath):
log = LoggerClass(log_path=__name__)
我认为入口点中 log
函数中的 start
对象将是第一个实例化的对象,但 log
对象是 {{1 的类属性}} 实际上是首先实例化的。这是因为在导入时评估类的类属性。就像导入一个类一样,这会导致对所有类属性进行评估。
所以我实际上只是将 Class2 中的代码更改为类似
Class2
当然,我将执行日志记录的语句从 import os
import subprocess
import other_stuff
class Class2:
log = None
def __init__(self):
def func2():
do stuff
@classmethod
def log(cls):
if cls.log is None:
cls.log = LoggerClass(log_name=__name__)
return cls.log
更改为 Class2.log.logstuff()
。因此,对日志内容的调用不再引用类属性 Class2.log().logstuff()
,而是调用类方法 log
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。