我希望在 python 3.3 中创建一个全局函数,例如 print 函数。特别是我们在自己的应用程序中嵌入了 python,我们希望公开一个简单的“调试(值)”全局函数,可用于任何脚本。我们可以通过将函数附加到模块来做到这一点,但是,为了方便起见,它更容易像 'print(value)' 那样是全局的。
您如何声明一个全局函数,该函数可用于任何没有导入的 python 文件,或者这是 python 中的黑盒?是否可以从 C 端绑定?
这几乎总是一个坏主意,但如果你真的想这样做……</p>
如果您打印出或以其他方式检查该print
功能,您会看到它在模块中builtins
。那是你的线索。所以,你可以这样做:
调试模块.py:
import builtins
builtins.debug = debug
现在,在 之后import debugmodule
,任何其他模块都可以调用debug
而不是debugmodule.debug
.
是否可以从 C 端绑定?
在 CPython 中,C 扩展模块基本上可以做与纯 Python 模块相同的事情。或者,更简单地说,用_debugmodule.so
C 编写 a,然后将 adebugmodule.py
导入并复制debug
到builtins
.
如果您要嵌入 CPython,您可以通过在启动脚本/交互式 shell/其他任何东西之前将函数注入builtins
模块来执行此操作,或者在以后的任何时间。
虽然这肯定有效,但并不完全清楚这是否真的保证有效。如果您阅读文档,它会说:
作为实现细节,大多数模块都将名称
__builtins__
作为其全局变量的一部分提供。的值__builtins__
通常是此模块或此模块__dict__
属性的值。由于这是一个实现细节,因此 Python 的替代实现可能不会使用它。
而且,至少在 CPython 中,实际上是__builtins__
作为查找链的一部分被搜索的模块或字典,而不是builtins
模块。因此,另一个实现可能会__builtins__
像 CPython 那样在 中查找内容,但同时不会使builtins
(或用户对其进行修改)在 中自动可用__builtins__
,在这种情况下,这是行不通的。(由于 CPython 是迄今为止唯一可用的 3.x 实现,因此很难推测……)
如果这在未来的 Python 3.x 实现中不起作用,我能想到的唯一选择是将你的函数注入每个模块,而不是内置函数。您可以使用PEP-302导入挂钩来做到这一点(这在 3.3 中比编写 PEP 302 时要容易得多……阅读导入系统了解详细信息)。
在 2.x 中,没有builtins
自动将东西注入到魔术模块__builtins__
中的模块,而是只有一个魔术模块__builtin__
(注意缺少s
)。您可能需要也可能不需要import
(为了安全起见,您也可以这样做)。你可能会也可能不会改变它。但它(至少)适用于 CPython 和 PyPy。
那么,正确的做法是什么?简单:而不是import debugmodule
, 只是from debugmodule import debug
在所有其他模块中。这样,它最终成为每个需要它的模块中的模块级全局。