具有 Python C 扩展的类(而不是方法)的完整且最小的示例?

use*_*ser 7 python cpython class python-c-api python-3.x

在任何地方,我都可以轻松找到有关使用Python C 扩展编写方法并在 Python 中使用它的示例。就像这个:Python 3 扩展示例

$ python3
>>> import hello
>>> hello.hello_world()
Hello, world!
>>> hello.hello('world')
Hello, world!
Run Code Online (Sandbox Code Playgroud)

如何编写一个 hello word 全功能 Python 类(而不仅仅是一个模块方法)?

我认为这How towrapp a C++ object using pure Python Extension API (python3)? 问题有一个例子,但它似乎并不小,因为他在上面使用(或包装?)C++ 类。

例如:

$ python3
>>> import hello
>>> hello.hello_world()
Hello, world!
>>> hello.hello('world')
Hello, world!
Run Code Online (Sandbox Code Playgroud)

这个带有 C 扩展的 Python 类示例的等价物是什么?

我会这样使用它:

from .mycextensionsmodule import ClassName

classname = ClassName("Hello")
classname.talk( 'world!' )
# prints "Hello world!"
Run Code Online (Sandbox Code Playgroud)

我的目标是编写一个完全用 C 编写的类以提高性能(我的项目中的所有其他类都将使用 Python,除了这个)。我并不是在寻找使用ctypes那样的可移植性,也不是在寻找使用Boost.PythonSWIG那样的黑匣子。只是一个纯粹用 Python C 扩展编写的高性能类。

完成这项Hello word工作后,我可以在 Python 扩展文档中找到自己的答案:

  1. https://docs.python.org/3/c-api/
  2. https://docs.python.org/3/extending/extending.html

use*_*ser 7

另请参阅:C 中的 Python 实例方法

创建名为的文件MANIFEST.in

include README.md
include LICENSE.txt

recursive-include source *.h
Run Code Online (Sandbox Code Playgroud)

创建名为的文件setup.py

include README.md
include LICENSE.txt

recursive-include source *.h
Run Code Online (Sandbox Code Playgroud)

创建名为的文件source/custom.cpp

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from setuptools import setup, Extension

__version__ = '0.1.0'

setup(
        name = 'custom',
        version = __version__,

        package_data = {
                '': [ '**.txt', '**.md', '**.py', '**.h', '**.hpp', '**.c', '**.cpp' ],
            },

        ext_modules = [
            Extension(
                name = 'custom',
                sources = [
                    'source/custom.cpp',
                ],
                include_dirs = ['source'],
            )
        ],
    )
Run Code Online (Sandbox Code Playgroud)

然后,要编译并安装它,您可以运行:

pip3 install . -v
python3 setup.py install
Run Code Online (Sandbox Code Playgroud)

作为这个问题的旁注How to use setuptools packages and ext_modules with the same name? 不要混合使用相同的项目*.py文件和 Python C 扩展,即仅使用纯 C/C++,构建 Python C 扩展而不添加packages = [ 'package_name' ]条目,因为它们会导致 Python C 扩展代码运行 30%,即,如果程序需要 7 秒运行,现在有*.py文件,需要 11 秒。

参考:

  1. https://docs.python.org/3/extending/newtypes_tutorial.html#supporting-circlic-garbage-collection

  • 我不确定从文档中复制和粘贴示例是否有价值 (3认同)