Python是一种解释性语言。但是为什么我的源目录包含。pyc文件,这些文件被Windows识别为“编译过的Python文件”?
当前回答
它们是由Python解释器在导入.py文件时创建的,它们包含导入模块/程序的“已编译字节码”,其思想是,如果.pyc比相应的.py文件更新,则可以在后续导入时跳过从源代码到字节码的“翻译”(只需完成一次),从而略微加快启动速度。但它仍然是被解释的。
其他回答
它们是由Python解释器在导入.py文件时创建的,它们包含导入模块/程序的“已编译字节码”,其思想是,如果.pyc比相应的.py文件更新,则可以在后续导入时跳过从源代码到字节码的“翻译”(只需完成一次),从而略微加快启动速度。但它仍然是被解释的。
语言规范与语言实现的重要区别是:
语言规范只是带有语言正式规范的文档,具有上下文无关的语法和语义规则定义(如指定基本类型和作用域动态)。 语言实现只是一个程序(编译器),它根据语言的规范实现语言的使用。
Any compiler consists of two independent parts: a frontend and backend. The frontend receives the source code, validate it and translate it into an intermediate code. After that, a backend translate it to machine code to run in a physical or a virtual machine. An interpreter is a compiler, but in this case it can produce a way of executing the intermediate code directly in a virtual machine. To execute python code, its necessary transform the code in a intermediate code, after that the code is then "assembled" as bytecode that can be stored in a file.pyc, so no need to compile modules of a program every time you run it. You can view this assembled python code using:
from dis import dis
def a(): pass
dis(a)
任何人都可以用Python语言构建静态二进制的编译器,就像可以构建C语言的解释器一样。有一些工具(lex/yacc)可以简化编译器的构建过程并使之自动化。
为了加速加载模块,Python将模块的编译内容缓存在.pyc中。
CPython将源代码编译为“字节码”,出于性能考虑,当源文件发生更改时,CPython会将此字节码缓存到文件系统中。这使得Python模块的加载速度更快,因为可以绕过编译阶段。当你的源文件是foo.py时,CPython将字节代码缓存在foo.py文件中。Pyc文件就在源代码旁边。
在python3中,Python的导入机制被扩展为在每个Python包目录中的单个目录中写入和搜索字节码缓存文件。这个目录将被称为__pycache__。
下面是一个描述如何加载模块的流程图:
欲了解更多信息:
裁判:PEP3147 参考:“编译”的Python文件
这是为初学者准备的,
在运行脚本之前,Python会自动将脚本编译为已编译的代码,即所谓的字节代码。
运行脚本不被认为是导入,也不会创建.pyc。
例如,如果你有一个脚本文件abc.py,它导入了另一个模块xyz.py,当你运行abc.py时,xyz.py, xyz.py。Pyc将被创建,因为xyz被导入,但没有abc。Pyc文件将被创建,因为abc.py没有被导入。
如果你需要为一个未导入的模块创建一个.pyc文件,你可以使用py_compile和compileall模块。
py_compile模块可以手动编译任何模块。一种方法是交互式地使用该模块中的py_compile.compile函数:
>>> import py_compile
>>> py_compile.compile('abc.py')
这将把.pyc写到与abc.py相同的位置(你可以用可选参数cfile重写它)。
您还可以使用compileall模块自动编译一个或多个目录中的所有文件。
python -m compileall
如果省略目录名(本例中的当前目录),模块将编译sys.path上的所有内容
Python(至少是它最常见的实现)遵循将原始源代码编译为字节码的模式,然后在虚拟机上解释字节码。这意味着(同样,最常见的实现)既不是纯解释器也不是纯编译器。
然而,另一方面,编译过程基本上是隐藏的——.pyc文件基本上被视为缓存;它们能加快速度,但你通常根本不需要注意到它们。它在必要时根据文件时间/日期戳自动使它们失效并重新加载(重新编译源代码)。
我所见过的唯一一次问题是,编译后的字节码文件以某种方式获得了未来的时间戳,这意味着它看起来总是比源文件更新。因为它看起来更新,源文件从来没有重新编译过,所以无论你做了什么更改,它们都被忽略了…
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录