为什么某些 CPython 的 lib 模块有 C 和 Python 实现?

问题描述 投票:0回答:1

我正在尝试改编标准库中的一些代码,当我查看 functools 时,我注意到每个“functool”后面都有这样的行:

try:
    from _functools import _lru_cache_wrapper
except ImportError:
    pass

来自 functools.py

在评论标题中我注意到了这个免责声明:

# Python module wrapper for _functools C module
# to allow utilities written in Python to be added
# to the functools module.

然后我注意到,在 functools c 模块中,有相同模块的实现,lru_cache 甚至讨论了它们之间的差异:

/* lru_cache object **********************************************************/

/* There are four principal algorithmic differences from the pure python version:
   1). The C version relies on the GIL instead of having its own reentrant lock.
   2). The prev/next link fields use borrowed references.
   3). For a full cache, the pure python version rotates the location of the
       root entry so that it never has to move individual links and it can
       limit updates to just the key and result fields.  However, in the C
       version, links are temporarily removed while the cache dict updates are
       occurring. Afterwards, they are appended or prepended back into the
       doubly-linked lists.
   4)  In the Python version, the _HashSeq class is used to prevent __hash__
       from being called more than once.  In the C version, the "known hash"
       variants of dictionary calls as used to the same effect.
*/

想必上面的导入只是意味着我们只导入C版本。如果 Python 实现会被覆盖,那为什么还要有它呢?我假设这是为了防止环境无法导入 C 版本,但是什么样的 CPython 解释器不能导入 C 模块?

python cpython
1个回答
0
投票

这是PEP 399所要求的:

从 Python 3.3 开始,添加到标准库的任何模块都必须具有纯 Python 实现。

来自基本原理

Python 已经超越了 CPython 虚拟机 (VM)。 IronPython、Jython 和 PyPy 目前都是 CPython VM 的可行替代方案。
...
此 PEP 的目的是通过强制添加到 Python 标准库的所有新模块必须具有纯 Python 实现(除非给予特殊豁免)来最大程度地减少这种重复工作。这确保了 stdlib 中的模块可用于所有 VM,而不仅仅是 CPython(不满足此要求的现有模块可以豁免,尽管没有什么可以阻止某人追溯添加纯 Python 实现)。

还提到了“覆盖纯Python实现”模式:

从纯 Python 实现访问加速代码的常见模式是使用

import *
导入它,例如
from _warnings import *
。这通常在模块末尾完成,以允许它用加速等效项覆盖特定的 Python 对象

© www.soinside.com 2019 - 2024. All rights reserved.