【问题标题】:Using Python3 C API to add to builtins使用 Python3 C API 添加到内置函数
【发布时间】:2018-04-13 18:09:45
【问题描述】:

我希望使用 Python3 C API 添加内置函数。我这样做只是为了帮助我熟悉 Python C API。 this 问题的答案很好地解释了为什么人们可能不想这样做。无论如何,我想在 Python builtins 模块中添加一个函数 foo

这是我到目前为止所做的 (foo.c):

#include <Python.h>
#include <stdio.h>

static PyObject*
foo(PyObject *self, PyObject *args){
    printf("foo called");
    return Py_None;
}

char builtin_name[] = "builtins";
char foo_name[] = "foo";
char foo_doc[] = "foo function";

static PyMethodDef foo_method = {foo_name, foo, METH_NOARGS, foo_doc};

PyMODINIT_FUNC
PyInit_foo(void){
    PyObject *builtin_module = PyImport_ImportModule(builtin_name);
    PyModule_AddFunctions(builtin_module, &foo_method);
    return builtin_module;
}

我将它放在 Python 源目录的 Modules/ 目录中。

【问题讨论】:

标签: python python-3.x python-c-api


【解决方案1】:

仅仅因为您将它放在Modules/ 文件夹中并使用Python-C-API 并不意味着它会自动编译和执行。在您将 foo.c 编译为 Python 扩展模块之后(您做了,对吗?)您的代码(大致)相当于:

foo.py

def foo():
    """foo function"""
    print("foo called")

import builtins
builtins.foo = foo

在 Python 实现中不那么简单的是,当您 import foo 时,它不会返回您的 foo 模块,而是 builtins。但我想说这根本不是一个好主意,特别是因为您要添加的内置函数与您创建的模块具有相同的名称,所以很可能import foo 您实际上会再次覆盖手动添加的builtins.foo。 ..

除此之外:仅仅将它放在Modules/ 文件夹中并不意味着它实际上是在您启动Python 时导入的。你要么需要自己使用import foo,要么修改你的Python启动来导入它。

好的,除此之外,您应该问自己以下问题:

  • 您想编译自己的 Python 吗?如果是,那么您只需编辑Python/ 文件夹中的bltinsmodule.c,然后完全编译Python。
  • 你甚至想要编译任何东西,而不是完整的 Python?如果是,那么只需创建你自己的扩展模块(基本上就像你已经做的那样),但不要将它放在 Python 的 Modules/ 文件夹中,而是真正创建一个包(完成 setup.py 等等)并且不要在 module-init 中返回 builtins 模块。只需创建一个空模块并在将foo 添加到builtins 模块后将其返回即可。并使用不同的模块名称,可能是_foo,这样它就不会与新添加的builtins.foo 函数冲突。
  • 在这种情况下,Python-C-API 和扩展模块是否正确?如果您认为 Python-C-API 可以更轻松地添加到 builtins,那么这是错误的。 Python-C-API 只是允许更快地访问和更多地访问 Python 功能。如果您只想做 Python 的东西(而不是与 C 库的接口),那么您可以用 C-API 做的事情很少,而用普通的 Python 模块做不到。我想说,对于您的用例来说,创建一个扩展模块完全是矫枉过正,所以也许只需要使用普通的 Python 模块。

我的建议是使用上面提到的foo.py,让Python在启动时导入它。为此,您将 foo.py 文件(我真的建议您将名称更改为 _foo.py 之类的名称)在安装附加软件包的目录中(Windows 上为 site-packages)并使用 PYTHONSTARTUP(或其他方法自定义启动)以在 Python 启动时导入该模块。

【讨论】:

  • 我想我只是对使用 Python-C-API 感兴趣。本质上,我试图做你对foo.py 所做的事情,但使用的是 C-API。我看到我需要澄清我的意图才能继续前进。
猜你喜欢
  • 1970-01-01
  • 2011-10-21
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 2015-05-04
  • 2012-08-07
相关资源
最近更新 更多