今天遇到一个问题,在测试项目中的一个大模型x时发现终端显示加载了两个模型,后来发现原来在import的时候导入的某些模块没有被注释掉,间接使另一个大模型y通过包的层层import默认执行其中的顶层代码被加载了出来,调了一下午才发现这个问题,详细记录一下出现这种问题的原理。
当你使用 import
导入一个模块时,Python 解释器会执行以下步骤:首先查找要导入的模块。如果找到了,Python 解释器会创建一个新的命名空间,并执行该模块的代码。在执行模块代码期间,定义的函数、类、变量等会被加载到模块的命名空间中。导入过程完成后,你可以通过模块名来访问其中定义的函数、类、变量等。在这个过程中,模块的顶层代码会被执行。所谓的顶层代码是指在模块中没有嵌套在任何函数或类定义中的代码。(这意味着如果顶层代码中包含执行某些函数的命令时,被加载到模块的命名空间中方法或者对象同样会被执行)。顶层代码可能包括函数或类的定义、全局变量的赋值、导入其他模块等。
接下来的内容是网络上搜索到的,也算是或许能用到的解决办法吧。不过我现在对所谓的“my_module.main()
函数只会在 my_module
被直接运行时才会执行”理解还不是很深刻,先放这里,随时回看。
如果模块中存在一些副作用,比如打印输出、执行函数等,这些副作用会在导入模块时被执行。这可能会导致意想不到的结果,特别是在你只是想导入模块而不执行其中的某些代码时。为了避免这种情况,你可以将那些只在直接运行模块时才需要执行的代码放在一个特殊的代码块中,即 if __name__ == "__main__":
。这样,这些代码只有在直接运行模块时才会执行,而在导入模块时不会执行,从而避免了副作用的发生。
# my_module.py
def some_function():
print("This is some function in my_module")
def main():
print("This is main function in my_module")
if __name__ == "__main__":
main()
# another_module.py
import my_module
# 调用 my_module 中的函数
my_module.some_function()
# 调用 my_module 中的 main 函数(只有在 my_module 直接运行时才会执行)
# 如果你不想执行 main 函数,可以直接注释掉下面这行代码
my_module.main()
通过 import my_module
导入了 my_module
模块。然后,你就可以使用 my_module
中定义的函数和类了。例如,你可以使用 my_module.some_function()
调用 some_function
函数。如果需要,你也可以调用 my_module.main()
函数,但这只会在 my_module
被直接运行时才会执行。