Lix*_*xas 228
没什么,因为python预编译你脚本到PYC文件并从它启动.只有在发生某种异常时 - 您可能会得到错误的解释,因为在行X中可能是启动脚本之前的不同代码
Nea*_*roo 26
当你运行 python 程序并且解释器启动时,首先发生的事情如下:
sys并被builtins初始化__main__被初始化,这是您作为参数提供给解释器的文件;这会导致您的代码执行当模块初始化时,它的代码就会运行,并在进程中定义类、变量和函数。模块(即主文件)的第一步可能是导入其他模块,这些模块将再次以相同的方式初始化;然后,它们生成的名称空间可供您的模块使用。导入过程的结果部分是内存中的模块(python-)对象。该对象确实具有指向 .py 和 .pyc内容的字段,但不再评估这些字段:模块对象被缓存,并且它们的源永远不会运行两次。因此,之后在磁盘上修改模块不会影响执行。当出于内省目的读取源代码时(例如抛出异常时或通过模块检查) ,它可能会产生影响。
这就是为什么if __name__ == "__main__"在添加不打算在导入模块时运行的代码时进行检查的原因。作为 main 运行该文件与导入该文件等效,只是__name__具有不同的值。
资料来源:
__main__:__main__- 顶级代码环境oxe*_*xer 18
这是一个有趣的问题。答案是“这取决于”。
考虑以下代码:
"Example script showing bad things you can do with python."
import os
print('this is a good script')
with open(__file__, 'w') as fdesc:
fdesc.write('print("this is a bad script")')
import bad
Run Code Online (Sandbox Code Playgroud)
尝试将上面的内容保存为“/tmp/bad.py”,然后执行“cd /tmp”,最后执行“python3 bad.py”,看看会发生什么。
在我的 ubuntu 20 系统上,我看到输出:
this is a good script
this is a bad script
Run Code Online (Sandbox Code Playgroud)
再说一次,你的问题的答案是“这取决于”。如果你没有做任何奇怪的事情,那么脚本就在内存中,你就没事了。但 python 是一种非常动态的语言,因此有多种方法可以修改“脚本”并使其影响输出。
如果您不想做任何时髦的事情,那么可能需要注意的事情之一就是函数内部的导入。
下面是另一个说明这个想法的例子(保存为“/tmp/modify.py”并执行“cd /tmp”,然后运行“python3 modify.py”)。下面定义的函数fiddle模拟您在脚本运行时修改脚本(如果需要,您可以删除 fiddle 函数,time.sleep(300)在倒数第二行添加 a ,然后自己修改文件)。
要点是,由于该show函数是在函数内部而不是在模块顶部进行导入,因此在调用该函数之前导入不会发生。如果您在调用之前修改了脚本show,则将使用您修改后的脚本版本。
如果您在修改正在运行的脚本时发现令人惊讶或意外的行为,我建议您在函数内查找 import 语句。有时有充分的理由去做这类事情,所以你会时不时地在人们的代码以及一些库中看到它。
下面演示了函数内部的导入如何导致奇怪的效果。您可以按原样尝试此操作,而不是注释掉对函数的调用,fiddle以查看在运行时修改脚本的效果。
"Example showing import in a function"
import time
def yell(msg):
"Yell a msg"
return f'#{msg}#'
def show(msg):
"Print a message nicely"
import modify
print(modify.yell(msg))
def fiddle():
orig = open(__file__).read()
with open(__file__, 'w') as fdesc:
modified = orig.replace('{' + 'msg' + '}', '{msg.upper()}')
fdesc.write(modified)
fiddle()
show('What do you think?')
Run Code Online (Sandbox Code Playgroud)