为什么在Python中导入模块会执行所有语句?

6
这是我的模块: test1.py
regions=["a","b","c"]
print "from test1 module"

test2.py

from test1 import regions
print "from test2 module", regions

运行test2.py文件

python test2.py 
from test1 module
from test2 module ['a', 'b', 'c']

我看到虽然我只从test1.py导入regions列表,但是打印语句print仍然被调用。我没有写import test1.py让一切都被执行。

1)为什么会执行test1.py文件中的所有内容(当然不包括__name__==__main__)?

2)如何只从test1模块中导入regions list而不执行所有其他语句?

我不知道这就是导入工作的方式,并且由于此问题而努力解决了3天的错误。


你还期望它做什么呢? - Wooble
3个回答

6
那就是导入的工作方式。
def my_function():
    print("Hello")

上面的代码片段是什么?它肯定是一个函数定义,但是在Python中,函数定义是语句,必须被执行才能定义函数。因此,当您导入上述模块时,它会执行“def”命令,创建一个新函数并将其分配给“my_function”。基本上就像这样:
my_function = ...definition..

当你导入一个模块时,你 总是 执行它的内容。否则,你将无法使用其中任何函数(或类)。

当然,Python 中还有其他定义函数的方法。

def create_my_function(x):
    def local_function():
        print(x)
    global my_function
    my_function = local_function

create_my_function("Hello")

这与原始定义的 my_function() 大体上是等价的。

由于在 Python 模块中可以放置任何语句,Python 无法知道哪些语句必须执行以定义您感兴趣的符号。因此,它必须执行所有语句。


如果我导入一个模块,我将该函数导入到当前命名空间。我认为当我导入常量时也应该适用。虽然它确实这样做,但它会执行导入模块中的其他语句。有没有办法,我只能导入常量。我不想在所有模块中重新声明常量。 - eagertoLearn
那么最好的方法是有一个专门用于常量的文件(避免使用内联语句)? - eagertoLearn
@eagertoLearn:你可以轻松地只导入常量,例如 from mymodule import MYCONST。然而,这必须导致执行mymodule中的所有顶级语句,因为这是常量获取其定义的方式。 - Dietrich Epp
@eagertoLearn:在Python中,顶层语句带有任何副作用被认为是极其不良的实践。安全地导入任何模块而不必担心会执行什么是应该的。 - Dietrich Epp

5

Python需要执行模块中的所有语句,因为它们可能具有相关的副作用。例如,请考虑:

a = 2
b = a*3

如果我从那个模块导入 b ,会发生什么? 通常情况下,除了主模块外的模块在导入时不应该有对程序运行有害的副作用。一般来讲,模块应该定义类、函数和变量,但不应该像打开文件、连接数据库等做其他事情。


如何仅导入常量。我不想在每个地方重新声明。 - eagertoLearn
@eagertoLearn:你可以非常容易地导入常量。但是,你无法避免执行语句。常量是使用语句定义的,因此如果你不执行这些语句,就无法获得这些常量。 - Dietrich Epp

1
这是导入模块的方式 - Python 在导入时执行该模块。这有其用途,因为您可以包含功能来验证依赖项或在导入模块实际调用任何类之前初始化功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接