python导入的缓存机制

问题来源:

logger文件

import sys

from loguru import logger

from app.internal.component.configer import settings


def configure_logger():
    """
    多进程环境,需要确保子进程能拿到正确初始化的logger实例
    :return:
    """
    logger.remove()


logger.add(settings.logFilePath, rotation=settings.logRotation, retention=settings.logRetention,
           enqueue=True, backtrace=True, diagnose=True, level=settings.logLevel,
           format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {file} | {line} |{message}")

logger.add(sys.stderr, enqueue=True, backtrace=True, diagnose=True, level=settings.logLevel,
           format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {file} | {line} | {message}")
print('load logger')

main文件中调用
from app.internal.component.logger import logger
会执行print语句输出: load logger
configure_logger()
然后执行子进程
每个子进程都会有from app.internal.component.logger import logger
但没有执行print语句,且Logger.info打印的日志也没有输出

为什么会这样呢

可以说明支进程加载logger时是没有真正加载那个文件的;从gpt4上得到的答案:
Python 的模块导入机制确实包含了一个缓存机制。当你第一次导入一个模块时,Python 会执行两个主要步骤:

  • 加载:Python 查找模块,编译成字节码(如果需要的话),然后执行模块的代码。
  • 缓存:一旦模块被加载,它会被缓存到一个名为 sys.modules 的字典中。
  • sys.modules 字典是 Python 用来跟踪已经加载模块的地方。字典的键是模块的名称,值是模块对象本身。如果你尝试再次导入同一个模块,Python 会首先检查 sys.modules 来看是否已经存在一个条目,如果存在,Python 就会使用缓存的模块而不是重新加载它。这就是为什么模块级别的代码(包括打印语句、函数定义等)只会在第一次导入时执行一次的原因。

如果你想要看到这个缓存机制的实际效果,你可以这样做:

import sys

# 查看sys.modules中的条目数量
print(len(sys.modules))

# 导入一个新模块
import math

# 再次查看sys.modules中的条目数量,应该增加了
print(len(sys.modules))

# 再次导入相同的模块并不会增加sys.modules中的条目数量
import math

# 数量保持不变
print(len(sys.modules))

# 显示math模块的缓存对象
print(sys.modules['math'])

这个缓存机制使得模块导入在性能上更加高效,因为它避免了重复的加载和初始化过程。然而,这也意味着如果模块中有可变的状态或者执行了某些操作(比如打印信息),这些只会在第一次导入时发生。

你可能感兴趣的:(python,缓存,java)