Cython:如何从单个文件导入多个类对象?

问题描述 投票:0回答:1

这就是我目前构建文件的方式。

CPP Folder
Cython Folder
├── setup.py
└── Geometry
    ├── Circle
    │   ├── __init__.py
    │   ├── Circle.pyx
    │   ├── Circle.pyi
    │   └── Circle.pxd
    └── Point
        ├── __init__.py
        ├── Point.pyx
        ├── Point.pyi
        └── Point.pxd 

这是我的 setup.py 文件

from setuptools import setup, Extension, find_packages
from Cython.Build import cythonize


point_extension = Extension(
    "Geometry.Point.Point",
    [
        "src/Geometry/Point/Point.pyx",
        "../cpp/lib/src/Point.cpp"
    ],
    include_dirs=[
        "../cpp/lib/include"
    ],
    libraries=["Some Library"],
    library_dirs=[
        "src/Geometry"
    ],
    extra_compile_args=["-std=c++17", "-O3"],
    language="c++"
)

circle_extension = Extension(
    "Geometry.Circle.Circle",
    [
        "../cpp/lib/src/Circle.cpp",
        "src/Geometry/Circle/Circle.pyx",
        "../cpp/lib/src/Point.cpp"
    ],
    include_dirs=[
        "../cpp/lib/include"
    ],
    libraries=["Some Library"],
    library_dirs=[
        "src/Geometry"
    ],
    extra_compile_args=["-std=c++17", "-O3"],
    language="c++"
)



setup(
    name="Geometry",
    version="0.1",
    packages=find_packages(where="src"),
    package_dir={"": "src"},
    package_data={
        "Geometry.Circle": ["*.so", "*.pyi"],
        "Geometry.Point": ["*.so", "*.pyi"]
    },
    ext_modules=cythonize([point_extension, circle_extension],
                          compiler_directives={"language_level": 3},
                          include_path=[
                                "../../Expression/cython/src/Some Library",
                                "src/Geometry",
                          ],
                          annotate=True),
    zip_safe=False,
)

通过此设置,当我想导入 Circle 或 Point 进行测试时,我必须执行以下操作:

from Geometry.Point import Point
from Geometry.Circle import Circle

我的目标是能够以这种方式导入它们:

from Geometry import Circle, Point

所以我认为我应该按如下方式构建我的文件:

CPP Folder
Cython Folder
├── setup.py
└── Geometry
    ├── __init__.py
    ├── Geometry.pyx
    ├── Geometry.pyi
    ├── Geometry.pxd
    ├── Circle
    │   ├── __init__.py
    │   ├── Circle.pyx
    │   ├── Circle.pyi
    │   └── Circle.pxd
    └── Point
        ├── __init__.py
        ├── Point.pyx
        ├── Point.pyi
        └── Point.pxd 

我应该如何重写我的

setup.py
并写出我的
Geometry.pxd, .pyx and .pyi
? 仅供参考,这是我的 Point.pxd 和 Point.pyx 的示例

**[Point.pxd]**
from libcpp.memory cimport shared_ptr, weak_ptr, make_shared
from Bryan cimport _Bryan, Bryan

cdef extern from "Point.h":
    cdef cppclass _Point:
        _Point(shared_ptr[_Bryan] x, shared_ptr[_Bryan] y, shared_ptr[_Bryan] z)
        shared_ptr[_Bryan] get_x()
        shared_ptr[_Bryan] get_y()
        shared_ptr[_Bryan] get_z()


cdef class Point:
    cdef shared_ptr[_Point] c_point

**[Point.pyx]**
from Point cimport *

cdef class Point:
    def __cinit__(self, Bryan x=Bryan("0", None), Bryan y=Bryan("0", None), Bryan z=Bryan("0", None)):
        self.c_point = make_shared[_Point](x.thisptr, y.thisptr, z.thisptr)

    def __dealloc(self):
        self.c_point.reset()

    def get_x(self) -> Bryan:
        cdef shared_ptr[_Bryan] result = self.c_point.get().get_x()
        cdef Bryan coord = Bryan("", None, make_with_pointer = True)
        coord.thisptr = result
        return coord

    def get_y(self) -> Bryan:
        cdef shared_ptr[_Bryan] result = self.c_point.get().get_y()
        cdef Bryan coord = Bryan("", None, make_with_pointer = True)
        coord.thisptr = result
        return coord

    def get_z(self) -> Bryan:
        cdef shared_ptr[_Bryan] result = self.c_point.get().get_z()
        cdef Bryan coord = Bryan("", None, make_with_pointer = True)
        coord.thisptr = result
        return coord

    property x:
        def __get__(self):
            return self.get_x()

    property y:
        def __get__(self):
            return self.get_y()

    property z:
        def __get__(self):
            return self.get_z()

谢谢你

python c++ cython cythonize
1个回答
0
投票

这是一个有点推测性的答案,因为我现在无法构建一个示例来编译 Cython 模块。我假设您的

setup.py
成功编译了模块。

您提出的目录结构是正确的,尽管您确实应该使用小写模块名称。所以:

CPP Folder
cython Folder
├── setup.py
└── geometry
    ├── __init__.py
    ├── geometry.pyx
    ├── geometry.pyi
    ├── geometry.pxd
    ├── circle
    │   ├── __init__.py
    │   ├── circle.pyx
    │   ├── circle.pyi
    │   └── circle.pxd
    └── point
        ├── __init__.py
        ├── point.pyx
        ├── point.pyi
        └── point.pxd

您需要更改

setup.py
以适应小写。完成此操作后,您可以将您的类“提升”(我不知道是否有专门术语)目录层次结构。然后它们将在父 (
geometry
) 命名空间下可用

__init__.py
目录中的
geometry
中,您放置:

from .circle import Circle
from .point import Point
© www.soinside.com 2019 - 2024. All rights reserved.