Python的几种文件类型

Python的几种文件类型

Python有以下几种类型的文件:

  • py:Python控制台程序的源代码文件
  • pyw:Python带用户界面的源代码文件
  • pyx:Python包源文件
  • pyc:Python字节码文件
  • pyo:Python优化后的字节码文件
  • pyd:Python的库文件(Python版DLL)、在Linux上是so文件

pyc和pyo的生成方法

pyc的作用是用来跨平台使用的,和Java中的Class文件类似。pyc文件是一种字节码文件,可以加快Python解释器的加载速度,当然也可以用来做简单的防源码泄露保护。

pyo则是优化过后的字节码文件,不过pyo更像编译型语言里的中间文件。

我们可以通过Python提供的py_compile模块来进行源代码的编译。

py_compile模块只提供3个方法,分别是有关编译异常PyCompileError、有关编译compile、有关程序入口main

我们要用到的是compile方法,compile原形如下:

compile(file, cfile=None, dfile=None, doraise=False, optimize=-1)

有5个参数:

  1. file:必选参数,要编译的源文件
  2. cfile:编译后的文件,默认在源文件目录下的__pycache__/源文件名.解释器类型-python版本.字节码类型 ###例如:__pycache__/abc.cpython-34.pyo
  3. dfile:错误消息文件,默认和cfile一样
  4. doraise:是否开启异常处理,默认False
  5. optimize:优化字节码级别

这里分为4个等级,文档中是这样写的:

optimize级别

param optimize: The optimization level for the compiler. Valid values are -1, 0, 1 and 2. A value of -1 means to use the optimization level of the current interpreter, as given by -O command line options.

optimize为1时,优化字节码级别为最高

-1和0:设置pyc优化级别

1和2:设置pyo优化级别

数字越小,优化级别越高

准备源文件a.py和b.py,内容相同,就是一句print("python")代码

编写编译脚本:

import py_compile

py_compile.compile(file = "a.py",cfile = "a.pyc",optimize=-1)

py_compile.compile(file = "b.py",cfile = "b.pyo",optimize=1)

编译脚本代码

运行后可以看到已经成功编译成字节码文件了,分别为a.pyc和b.pyo

用文本编辑器打开a.pyc和b.pyo,如图

打开字节码文件,尝试运行这2个字节码文件。

运行效果

可见,字节码文件成功运行。

也可以直接通过Python加载模块来运行:

#编译成pyc

python -m py_compile 源代码

#编译成pyo

python -O -m py_compile 源代码

这确实可以简单地保护我们的代码,同时似乎看起来像是加密的效果,但是要注意,这不是加密,只是把源码变成优化后的字节码而已,如果想要获得源码,我们一样可以通过逆向编译来得到源码,目前有专门逆向Python字节码的工具存在。

如果需要编译整个目录内的所有源代码,请参考Python compileall

pyd可以让我们的代码更安全

如果真的想要保护代码,为何不考虑把它变成python扩展模块?(目前还没有pyd被反编译的消息)

pyd是Python中的扩展模块,相当于windows的dll,不同的是pyd只供python调用而已。

实际上,大部分的包、小模块都是以pyd形式发布的。

如果特别感兴趣的小伙伴可以深入研究下setuptools和distutils

在把源代码转换成功pyd之前,我们需要用到Cython包。

pip list | findstr "Cython"

检查Cython包

检查是否安装了Cython,没有请pip install Cython安装即可

编译pyd步骤1:生成C代码

import Cython.Build

#导入Build模块

Cython.Build.cythonize("a.py")

#a.py转换成C代码

cythonize运行完成之后,无异常的情况下会在a.py的目录下创建一个a.c文件,同时会返回一个distutils.extension.Extension对象列表

一定要注意的是:如果在Python Shell测试,一定要用绝对路径,否则会ValueError异常,cythonize不会从sys.path中读路径。

编译pyd步骤2:利用distutils生成pyd扩展模块

此时我们可以用distutils包来编译成我们要的pyd模块

编译a.py成pyd

import Cython.Build

import distutils.core

a = Cython.Build.cythonize("a.py")

#返回distutils.extension.Extension对象列表

distutils.core.setup(

name = 'pyd的编译',#包名称

version = "1.0",#包版本号

ext_modules= a,#扩展模块

author = "百家号——斌哥说Python",#作者

author_email='binnlzeng@163.com'#作者邮箱

)

代码

python 执行编译的脚本 build

python 执行编译的脚本 build_ext

执行编译脚本编译

此时会在编译脚本所在目录生成一个build目录,里面存着C语言的.def文件和.o文件,还有我们要的pyd文件

生成的C文件

生成的pyd文件

批量编译pyd文件的误区

此时我们已经生成了1个pyd文件,如果我们是扩展包/模块的开发者,怎么批量编译呢?

总有人会犯错,例如以下2个例子:

a = Cython.Build.cythonize("a.py")

b = Cython.Build.cythonize("b.py")

distutils.core.setup(

...,

ext_modules= [a,b]

)

这样做吗?NO......

a = Cython.Build.cythonize("a.py")

a.append(Cython.Build.cythonize("b.py"))

distutils.core.setup(

...,

ext_modules= a

)

还是这样?

犯这样的错原因却是因为:

a = Cython.Build.cythonize("a.py")

type(a)

提示<class 'list'>

没错,Cython.Build.cythonize返回的是一个列表,里面有只有1个distutils.extension.Extension对象

报错如下:

异常信息

需要1个Extension或者是2个元组

批量编译pyd

方法1:提取我们要的Extension对象

import Cython.Build

import distutils.core

a = Cython.Build.cythonize("a.py")[0] #提取Extension对象

b = Cython.Build.cythonize("b.py")[0]

distutils.core.setup(

name = 'pyd的编译', #包名称

version = "1.0", #包版本号

ext_modules= [a,b], #被扩展的模块

author = "百家号——斌哥说Python", #作者

author_email='binnlzeng@163.com' #作者邮箱

)

方法2:转换成C代码后再进行Extension对象实例化

import Cython.Build

import distutils.core

Cython.Build.cythonize("a.py")

Cython.Build.cythonize("b.py")

distutils.core.setup(

name = 'pyd的编译', #包名称

version = "1.0", #包版本号

ext_modules= [distutils.core.Extension('a',["a.c"]),distutils.core.Extension('b', ['b.c'])], #被扩展的模块

#[

#distutils.core.Extension('a',["a.c"]),

#distutils.core.Extension('b', ['b.c'])

#]

author = "百家号——斌哥说Python", #作者

author_email='binnlzeng@163.com' #作者邮箱

)

pyc和pyo相对而言安全性较低,pyd是目前解决Python开发中代码安全性最优的一个方案。

但是要注意一点:无论是pyc还是pyo、pyd,都是跟着Python版本走的,不要指望Python2.7的东西在Python3上完美运行。

PS:如果遇到running build...提示,删掉build目录重新编译即可。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python可以使用多种库来读取不同类型的文件,下面以几种常见的文件类型为例进行说明。 1. 读取文本文件Python内置的`open()`函数可以用于打开文本文件,并使用`read()`方法来获取文件内容。例如,可以使用以下代码读取名为`example.txt`的文本文件: ```python with open('example.txt', 'r') as file: content = file.read() ``` 在这个例子中,将文件名`example.txt`作为参数传递给`open()`函数,并使用`'r'`模式来指定以只读方式打开文件。然后,通过`read()`方法来获取文件的内容,并将其保存在变量`content`中。可以根据具体需求进行进一步处理。 2. 读取CSV文件Python的`csv`库提供了用于读取和写入CSV文件的功能。例如,可以使用以下代码读取名为`data.csv`的CSV文件: ```python import csv with open('data.csv', 'r') as file: reader = csv.reader(file) for row in reader: print(row) ``` 在这个例子中,首先导入`csv`库,然后使用`open()`函数打开`data.csv`文件,并传递给`csv.reader()`函数来创建一个CSV读取器对象。然后,可以使用`for`循环逐行读取文件中的每一行,并将其打印出来。 3. 读取Excel文件Python的`pandas`库提供了用于读取Excel文件的功能。例如,可以使用以下代码读取名为`data.xlsx`的Excel文件: ```python import pandas as pd data = pd.read_excel('data.xlsx') print(data) ``` 在这个例子中,首先导入`pandas`库,并使用`read_excel()`函数来读取`data.xlsx`文件。读取后的Excel数据将以一个`DataFrame`对象的形式返回,并可以通过`print()`函数来显示。 除了上述提到的文本、CSV和Excel文件Python还可以使用其他库来读取各种类型的文件,如`json`库读取JSON文件、`PIL`库读取图像文件等。具体的读取方法会因文件类型和具体需求而有所不同,通过查阅相关库的文档可以获取更详细的使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值