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'])

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

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值