为什么 Python 在导入模块时运行它?如何停止它?
我正在构建一个 Python 程序,可以通过两种方式运行:第一种是调用 python main.py,它会以友好的方式提示用户输入,然后运行用户通过程序输入。另一种方法是调用 python batch.py -file- ,它将传递所有友好的输入收集,并通过程序在单个文件中运行整个文件的输入。去。
问题是,当我运行 batch.py
时,它从 main.py
导入一些变量/方法/等,当它运行此代码
import main
时 :程序立即出错,因为它尝试运行 main.py
中的代码。
如何阻止 Python 运行我正在导入的 main
模块中包含的代码?
I have a Python program I'm building that can be run in either of 2 ways: the first is to call python main.py
which prompts the user for input in a friendly manner and then runs the user input through the program. The other way is to call python batch.py -file-
which will pass over all the friendly input gathering and run an entire file's worth of input through the program in a single go.
The problem is that when I run batch.py
, it imports some variables/methods/etc from main.py
, and when it runs this code:
import main
at the first line of the program, it immediately errors because it tries to run the code in main.py
.
How can I stop Python from running the code contained in the main
module which I'm importing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
因为这就是 Python 的工作方式 - 诸如
class
和def
之类的关键字不是声明。相反,它们是被执行的实时语句。如果它们没有被执行,你的模块将是空的。惯用的方法是:
Because this is just how Python works - keywords such as
class
anddef
are not declarations. Instead, they are real live statements which are executed. If they were not executed your module would be empty.The idiomatic approach is:
由于 Python 的工作方式,它有必要在导入模块时运行它们。
要防止模块中的代码在导入时执行,但仅在直接运行时执行,您可以使用此
if
来保护它:您可能希望将此代码放在
main() 方法,这样您可以直接执行文件,也可以导入模块并调用
main()
。例如,假设它位于文件foo.py
中。该程序可以通过 python foo.py 运行,也可以从另一个 Python 脚本运行:
Due to the way Python works, it is necessary for it to run your modules when it imports them.
To prevent code in the module from being executed when imported, but only when run directly, you can guard it with this
if
:You may want to put this code in a
main()
method, so that you can either execute the file directly, or import the module and call themain()
. For example, assume this is in the filefoo.py
.This program can be run either by going
python foo.py
, or from another Python script:使用
if __name__ == '__main__'
习惯用法 --__name__
是一个特殊变量,如果模块正在运行,其值为'__main__'
作为脚本,以及模块名称(如果导入)。所以你会做类似的事情Use the
if __name__ == '__main__'
idiom --__name__
is a special variable whose value is'__main__'
if the module is being run as a script, and the module name if it's imported. So you'd do something like不幸的是,你没有。这是导入语法工作原理的一部分,这样做很重要——记住
def
实际上是执行的东西,如果 Python 没有执行导入,你就会被困住,没有功能。不过,由于您可能有权访问该文件,因此您也许可以查看导致错误的原因。可以修改您的环境来防止错误发生。
Unfortunately, you don't. That is part of how the import syntax works and it is important that it does so -- remember
def
is actually something executed, if Python did not execute the import, you'd be, well, stuck without functions.Since you probably have access to the file, though, you might be able to look and see what causes the error. It might be possible to modify your environment to prevent the error from happening.
有一个 Python 增强提案 PEP 299 旨在替换
if __name__ == '__main__':
成语与def __main__:
,但被拒绝了。了解使用if __name__ = '__main__':
时要记住的内容仍然是一本好书。There was a Python enhancement proposal PEP 299 which aimed to replace
if __name__ == '__main__':
idiom withdef __main__:
, but it was rejected. It's still a good read to know what to keep in mind when usingif __name__ = '__main__':
.将代码放入函数中,直到调用该函数后它才会运行。您的
main.py
中应该有一个 main 函数。语句:然后,如果您调用
python main.py
,则main()
函数将运行。如果您导入main.py
,则不会。另外,为了清楚起见,您可能应该将main.py
重命名为其他名称。Put the code inside a function and it won't run until you call the function. You should have a main function in your
main.py
. with the statement:Then, if you call
python main.py
themain()
function will run. If you importmain.py
, it will not. Also, you should probably renamemain.py
to something else for clarity's sake.我做了一个简单的测试:
#test.py
#test2.py
执行或运行test2.py时,运行结果:
结论:导入模块时不添加
if __name__ ==“__main__”:
,运行当前模块,导入模块中不在函数中的代码依次执行,不在函数中的代码则不执行叫。此外:
I did a simple test:
#test.py
#test2.py
When executing or running test2.py, the running result:
Conclusion: When the imported module does not add
if __name__=="__main__":
, the current module is run, The code in the imported module that is not in the function is executed sequentially, and the code in the function is not executed when it is not called.in addition:
你可以这样写你的“main.py”:
You may write your "main.py" like this:
可能发生的一个小错误(至少发生在我身上),特别是在分发执行完整分析的 python 脚本/函数时,是直接在函数 .py 文件末尾调用该函数。
用户唯一需要修改的是输入文件和参数。
导入时这样做,您将立即运行该函数。为了正确的行为,您只需删除对函数的内部调用并将其保留给真正的调用文件/函数/代码部分
A minor error that could happen (at least it happened to me), especially when distributing python scripts/functions that carry out a complete analysis, was to call the function directly at the end of the function .py file.
The only things a user needed to modify were the input files and parameters.
Doing so when you import you'll get the function running immediately. For proper behavior, you simply need to remove the inside call to the function and reserve it for the real calling file/function/portion of code
另一种选择是使用二进制环境变量,例如我们将其称为“run_code”。如果run_code = 0(False)构造main.py来绕过代码(但暂时绕过的函数仍会作为模块导入)。稍后,当您准备使用导入的函数(现在是一个模块)时,设置环境变量 run_code = 1 (True)。使用 os.environ 命令设置和检索二进制变量,但请确保在检索时将其转换为整数(或重构 if 语句以读取字符串值),
在 main.py 中:
...在任何脚本中加载 main.py:
输出:不。不做。
输出:执行代码...
*注意:上面的代码假定 main.py 以及导入它的任何脚本都存在于同一目录中。
Another option is to use a binary environment variable, e.g. lets call it 'run_code'. If run_code = 0 (False) structure main.py to bypass the code (but the temporarily bypassed function will still be imported as a module). Later when you are ready to use the imported function (now a module) set the environment variable run_code = 1 (True). Use the os.environ command to set and retrieve the binary variable, but be sure to convert it to an integer when retrieving (or restructure the if statement to read a string value),
in main.py:
...in whatever script is loading main.py:
OUTPUT: nope. not doing it.
OUTPUT: executing code...
*Note: The above code presumes main.py and whatever script imports it exist in the same directory.
虽然你不能在不运行代码的情况下使用
import
;有一种非常快捷的方法可以输入变量;通过使用 numpy.savez,它将变量作为 numpy 数组存储在 .npz 文件中。之后,您可以使用 numpy.load 加载变量。请参阅 scipy 文档中的完整说明
请注意这一点仅适用于变量和变量数组,不适用于方法等。
Although you cannot use
import
without running the code; there is quite a swift way in which you can input your variables; by usingnumpy.savez
, which stores variables as numpy arrays in a .npz file. Afterwards you can load the variables usingnumpy.load
.See a full description in the scipy documentation
Please note this is only the case for variables and arrays of variable, and not for methods, etc.
尝试从 main.py 导入所需的函数?因此,
可能您在batch.py中为一个函数命名为与main.py中的函数相同,并且当您导入main.py时,程序运行main.py函数而不是batch.py函数;执行上述操作应该可以解决这个问题。我希望。
Try just importing the functions needed from main.py? So,
It could be that you've named a function in batch.py the same as one in main.py, and when you import main.py the program runs the main.py function instead of the batch.py function; doing the above should fix that. I hope.