网站首页 > 基础教程 正文
我们在运行Python文件的过程中有时会多出来几个同名文件,但是文件后缀从.py变成了.pyc 。如下图有三个py文件,在start_here.py里import了common.py和unit.py 。
上面是还没运行前的三个.py文件,我们python start_here.py运行一下再看看:
运行后看上图,多出来两个pyc文件,分别是common.pyc和unit.pyc 。
1.有没有好奇为什么会多出来两个.pyc文件?
2.为什么start_here.py文件又没有pyc文件?
接下来就来说清楚这个两个问题。
这里啰嗦一下,我们都知道计算机是不认识你在代码里写的那一行行字母的,计算机只认二进制,也只执行二进制文件,我们写的代码是需要编译器编译成二进制的。
.pyc文件是干什么的
对于Python来说你写的Python代码在执行python xxx.py时会由Python解析器翻译成PyCodeObject对象,俗称字节码(byte code),然后交由Python虚拟机来执行字节码(PS:字节码才是可执行的)。
在这个过程中这些字节码都是在内存中的,众所周知Python的运行性能不如编译性语言(比如C语言,JAVA …),所以Python在程序执行结束后会把字节码写入到硬盘中,保存为.pyc文件,目的是下一次再执行python xxx.py程序时,Python会先在目录下找xxx.pyc文件来执行,因为.pyc文件里保存的是字节码,所以就节省了Python解析器把xxx.py翻译成字节码的时间,所以就提高了性能。
总结就是.pyc文件是一个可执行的字节码文件,目的是节省Python解析器翻译时间,提高运行效率。其实性能只会提高那么一丢丢,大型项目.py文件很多的话,猿人学Python测试过节省的时间就多一点。
我们同样可以像执行py文件一样来执行pyc文件:
什么时候会生成.pyc文件
第一次执行python程序后,被import的py文件会生成.pyc字节码文件,比如我的截图里举的例子,我在start_here.py文件里import了common.py和unit.py,执行程序后就生成了common.pyc和unit.pyc,没有生成start_here.pyc,因为它没有被import。
当第二次再执行程序时,Python就会拿.pyc文件和.py文件的修改时间对比,如果pyc文件修改时间大于py文件的话,说明py源文件没有被修改,Python就会直接执行.pyc文件;如果.py文件的修改时间比.pyc新的话,说明源文件被修改过,Python就会重新执行.py文件来重新生成字节码。
如果你想让所有py文件都生成pyc文件的话,可以执行:
python -m compileall .
别忘了compileall后面还有一个 . ,会把当前目录里py文件都生成pyc。
其它pyc知识
其实我们安装的Python第三方库还是Python自带的包(模块),都会在该目录下生成一个’__pycache__’目录,目录里全是该包(模块)的pyc文件,来看看。
python3.5之后只要你的目录里有__main__.py这个文件,运行命令
python dir(具体的python目录),就会在该dir下生成__pycache__目录,里面是该dir里的pyc文件。
另外提供一个骚操作,因为pyc文件是字节码,是二进制文件,所以反编译出源代码是比较麻烦的,所以如果是项目交付性质,不想交源代码的话,可以把pyc文件给对方。只是一个想法,没有实践过。
猜你喜欢
- 2024-10-12 python代码是如何执行的? python的代码如何运行
- 2024-10-12 deepin os下使用Geany编写python程序
- 2024-10-12 扩展和嵌入 Python 之重定向输出与编译
- 2024-10-12 python爬虫数据匹配-正则(re模块的用法)
- 2024-10-12 解锁 Python 中的正则表达式:轻松搞定文本处理
- 2024-10-12 Python 的底层 — 解释器和内存管理,你了解多少
- 2024-10-12 python程序执行原理 描述python程序执行原理
- 2024-10-12 这些 python 技巧,不知道就 out 了
- 2024-10-12 “挑战用 500 行 Python 写一个 C 编译器”
- 2024-10-12 python接口自动化测试之接口数据依赖
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)