当我导入我的模块时,为什么Python正在运行我的模块,我如何停止它?

我有一个我正在构建的Python程序,可以以两种方式之一运行:第一种是调用python main.py,它以友好的方式提示用户输入,然后通过程序运行用户输入。另一种方法是调用python batch.py -file-,它将传递所有友好的输入收集,并通过程序一次运行整个文件的输入值。

问题是,当我运行batch.py时,它从main.py导入了一些变量/方法/等,并且当它运行以下代码时:

import main

在程序的第一行,它立即错误,因为它试图运行main.py中的代码。

如何阻止Python运行我正在导入的main模块中包含的代码?

239875 次浏览

不幸的是,你不知道。这是导入语法工作方式的一部分,它这样做很重要——记住def实际上是执行的东西,如果Python不执行导入,你就会,嗯,没有函数。

不过,由于您可能有权访问该文件,因此您可能能够查看导致错误的原因。可以通过修改环境来防止错误的发生。

使用if __name__ == '__main__'习惯用法——__name__是一个特殊变量,如果模块作为脚本运行,其值为'__main__',如果模块被导入,则为模块名。所以你会这样做

# imports
# class/function definitions
if __name__ == '__main__':
# code here will only run when you invoke 'python main.py'

你可以这样写"main.py":

#!/usr/bin/env python


__all__=["somevar", "do_something"]


somevar=""


def do_something():
pass #blahblah


if __name__=="__main__":
do_something()

因为这就是Python的工作方式——关键字如classdef声明。相反,它们是被执行的真正的生活语句。如果它们没有被执行,您的模块将是空的。

惯用的方法是:

# stuff to run always here such as class/def
def main():
pass


if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()

但是,它确实需要对导入的模块进行源代码控制。

由于Python的工作方式,当它导入模块时,有必要运行它们。

为了防止模块中的代码在导入时被执行,但只在直接运行时执行,你可以使用if来保护它:

if __name__ == "__main__":
# this won't be run when imported

你可能想把这段代码放在main()方法中,这样你就可以直接执行文件,或者导入模块并调用main()。例如,假设它在文件foo.py中。

def main():
print "Hello World"


if __name__ == "__main__":
main()

这个程序既可以通过python foo.py运行,也可以通过另一个Python脚本运行:

import foo


...


foo.main()

试着从main.py导入所需的函数?所以,

from main import SomeFunction

可能是你在batch.py中命名的函数与main.py中的函数相同,当你导入main.py时,程序运行main.py函数而不是batch.py函数;执行上述操作可以解决这个问题。我希望。

将代码放入函数中,直到调用该函数它才会运行。在main.py中应该有一个main函数。声明如下:

if __name__ == '__main__':
main()

然后,如果调用python main.pymain()函数将运行。如果你导入main.py,它不会。此外,为了清晰起见,你可能应该将main.py重命名为其他东西。

虽然你不能在不运行代码的情况下使用import;有一种非常快速的方法可以输入你的变量;通过使用numpy.savez,它将变量存储为.npz文件中的numpy数组。之后你可以使用numpy.load加载变量。

参见完整描述在scipy文档中

请注意,这只适用于变量和变量数组,而不适用于方法等。

有一个Python增强提议PEP 299,旨在用def __main__:取代if __name__ == '__main__':成语,但它被拒绝了。它仍然是一本很好的阅读,以了解在使用if __name__ = '__main__':时要记住什么。

我做了一个简单的测试:

# test.py

x = 1
print("1, has it been executed?")




def t1():
print("hello")
print("2, has it been executed?")




def t2():
print("world")
print("3, has it been executed?")




def main():
print("Hello World")
print("4, has it been executed?")




print("5, has it been executed?")
print(x)


# while True:
# t2()


if x == 1:
print("6, has it been executed?")

# test2.py

import test

当执行或运行test2.py时,运行结果:

1, has it been executed?


5, has it been executed?


1


6, has it been executed?

结论:当导入的模块没有添加if __name__=="__main__":时,当前模块将运行,导入模块中不在函数中的代码将按顺序执行,函数中未被调用的代码将不执行。

此外:

def main():
# Put all your code you need to execute directly when this script run directly.
pass


if __name__ == '__main__':
main()
else:
# Put functions you need to be executed only whenever imported
可能发生的一个小错误(至少发生在我身上),特别是在分发执行完整分析的python脚本/函数时,是直接在函数.py文件的末尾调用函数。 用户只需要修改输入文件和参数。 在导入时这样做,函数将立即运行。为了实现正确的行为,只需删除对函数的内部调用,并将其保留给真正调用文件/函数/代码

的部分