为什么我需要从 Crypto 导入 Hash 和从 Crypto.Cipher 导入 PKCS1_OAEP 才能使 Hash.MD5 工作?

Why do I need to import both Hash from Crypto and PKCS1_OAEP from Crypto.Cipher for Hash.MD5 to work?

同时使用 PKCS1_OAEP 和 Hash

from Crypto.Cipher import PKCS1_OAEP
from Crypto import Hash

Hash.MD5

该代码可以正常工作。

仅哈希

from Crypto import Hash

Hash.MD5

该代码给我以下错误:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    Hash.MD5
AttributeError: module 'Crypto.Hash' has no attribute 'MD5'

只有 PKCS1_OAEP

这也不行:

from Crypto.Cipher import PKCS1_OAEP

Hash.MD5

出现此错误:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    Hash.MD5
NameError: name 'Hash' is not defined

我觉得它应该只与 from Crypto import Hash 一起工作,但显然不是这样。有什么想法吗?

(我是 运行 Python 3.8.3)

我在 https://discuss.python.org/t/why-do-i-need-to-import-both-hash-from-crypto-and-pkcs1-oaep-from-crypto-cipher-for-hash-md5-to-work/6840/3 上发布了这篇文章,这是我收到的回复:


我认为问题在于 Crypto.Hash 本身就是一个包,而不是 模块。这意味着里面有一个MD5模块 Crypto.Hash.

当您导入 Crypto.Hash 时,它会运行文件 …/site-packages/Crypto/Hash/init.py。这将定义各种 名称(可能 none - 它通常是一个空的占位符),但 不会 固有地导入它旁边的所有模块。

所以当你“import Crypto.Hash”你会得到名字“Hash”包含 Hash 包中的 init.py 文件定义的东西。那 并不意味着有一个 Hash.MD5 名称。

相反,“from Crypto.Hash import MD5”从 Crypto.Hash package(模块集合)即 Crypto.Hash.MD5 模块本身,并在您自己的命名空间中为其命名为“MD5”。

此处“API 原则”下有一个该表格的示例:

https://www.pycryptodome.org/en/latest/src/hash/hash.html

其中:

from Crypto.Hash import SHA256

我同意这是一个不幸的用户体验(您是用户)。