只有在.pyc文件过期时才编译吗?
有没有办法把一个.py脚本编译成.pyc,但只有在它缺失或落后于 the.py 文件时才进行编译?
我想在必要时编译该文件,然后在Python内部运行它,exec() 能运行.pyc文件吗?
import py_compile
py_compile.compile('Child.py')
exec(open('Child.py').read())
这可行,但每次运行都会重新编译该文件。
在jsbueno的注释基础上——一个更全面的示例:
Parent.py
def main():
class cParent:
test = "test"
oParent = cParent()
print("In parent 1")
import py_compile
py_compile.compile('Child1.py')
exec(open('Child1.py').read(), {}, {"oParent":oParent})
print("In parent 2")
Child1.py
print("In child 1")
print(oParent.test)
print("In child 2")
解决方案
你得到的结果是什么?因为Python对 PYC文件的默认编译启发式已经做到这一点:如果文件过时就会重新构建。此外,这有点复杂——可以复现这种行为,但理想情况下,为了覆盖所有边缘情况,你需要跟踪源代码哈希、当前环境的Python版本与体系结构等……所有这些都内置在语言的导入机制中。
例外的是你调用的主Python文件:如果你不是把应用打包成一个包,而是把大量应用程序放在一个大的 ".py" 文件中,直接用 "python myapp.py" 调用——那么这个文件每次都会被重新编译。
所以,回到你的问题——问题在于你显式地编译了你的文件;如果你只是导入它,并调用其中一个可用作入口点的函数,而不是通过exec,那么你就能受益于上面的启发式规则。
import Child
Child.entry()
并在 Child.py 内,将代码重新排列,使模块的顶层不执行代码,而是在调用某个函数时再执行——然后编写这个 entry 函数来运行该代码:
Child.py - 之前
my()
spread_Apart()
with_side_effects_on_toplevel()
code()
变为:
Child.py - 之后:
def entry():
my()
spread_Apart()
with_side_effects_on_toplevel()
code()
if __name__ == "__main__":
# this if guard ensures the previous behavior is unchanged
# when the file is called directly from CLI
entry()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。