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