{site_name}

{site_name}

🌜 搜索

Python PEP 552 是指引入一种新的基于哈希值的 .pyc 文件格式,

Python 𝄐 0
python中哈希用法,python的哈希函数,python中的哈希算法,python的哈希表,哈希表 python,哈希算法 python
Python PEP 552 是指引入一种新的基于哈希值的 .pyc 文件格式,这样可以更好地支持 Python 源代码的安全性和可移植性。该 PEP 的主要目标是解决以下两个问题:

1. 当 Python 解释器加载 .pyc 文件时,如果文件内容被更改过,则会直接加载修改后的内容,这可能导致不安全的代码执行。

2. 在不同系统上编译的 .pyc 文件可能不兼容,不能在其他系统上正确运行。

为了解决这些问题,PEP 552 引入了一种新的 .pyc 格式,在编译源代码时使用哈希函数对源代码内容进行哈希处理,并将哈希值存储在 .pyc 文件头部。每次加载 .pyc 文件时,解释器都会检查源代码内容的哈希值是否与 .pyc 文件头部中的哈希值相同。如果不同,则说明源文件已经被修改过,解释器将拒绝加载此文件并抛出异常。

下面是一个使用 Python 3.7.3 版本编写的示例程序:

python
# hash_example.py

def main():
print("Hello, World!")

if __name__ == '__main__':
main()


可以使用 Python 3.7.3 编译这段代码,并生成一个名为 hash_example.cpython-37.pyc 的 .pyc 文件。接下来,我们可以修改源代码中的字符串,再次编译并尝试运行:

python
# hash_example.py

def main():
print("Hello, World! (modified)")

if __name__ == '__main__':
main()


使用 Python 3.7.3 编译此代码会生成一个新的 .pyc 文件 hash_example.cpython-37.pyc。但如果我们尝试在 Python 3.7.3 解释器中加载旧的 .pyc 文件,解释器将拒绝加载:

python
>>> import importlib.util
>>> importlib.util.cache_from_source('hash_example.py')
'__pycache__/hash_example.cpython-37.pyc'
>>> importlib.util.cache_from_source('hash_example.py')[:-1] + 'x'
'__pycache__/hash_example.cpython-37.pycx'
>>> with open('__pycache__/hash_example.cpython-37.pyc', 'rb') as f:
... data = f.read()
...
>>> with open('__pycache__/hash_example.cpython-37.pycx', 'wb') as f:
... f.write(data)
...
>>> import hash_example
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: Bad magic number in __pycache__/hash_example.cpython-37.pycx


这是因为新的 .pyc 文件和旧的 .pyc 文件具有不同的哈希值,所以 Python 解释器无法正确地加载旧的文件。