2

我希望在 python 3.3 中创建一个全局函数,例如 print 函数。特别是我们在自己的应用程序中嵌入了 python,我们希望公开一个简单的“调试(值)”全局函数,可用于任何脚本。我们可以通过将函数附加到模块来做到这一点,但是,为了方便起见,它更容易像 'print(value)' 那样是全局的。

您如何声明一个全局函数,该函数可用于任何没有导入的 python 文件,或者这是 python 中的黑盒?是否可以从 C 端绑定?

4

1 回答 1

4

这几乎总是一个坏主意,但如果你真的想这样做……</p>

如果您打印出或以其他方式检查该print功能,您会看到它在模块中builtins。那是你的线索。所以,你可以这样做:

调试模块.py:

import builtins
builtins.debug = debug

现在,在 之后import debugmodule,任何其他模块都可以调用debug而不是debugmodule.debug.


是否可以从 C 端绑定?

在 CPython 中,C 扩展模块基本上可以做与纯 Python 模块相同的事情。或者,更简单地说,用_debugmodule.soC 编写 a,然后将 adebugmodule.py导入并复制debugbuiltins.

如果您要嵌入 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在所有其他模块中。这样,它最终成为每个需要它的模块中的模块级全局。

于 2013-04-02T18:24:10.377 回答