关于带有C扩展的Python项目:带有C扩展的Python项目 – 结构,导入和测试

Python project with C extensions - structure, imports and tests

一个用python编写的项目,带有一些C扩展(不使用SWIG等)。我试图弄清楚如何构建我的项目,以便:

  • 进口工作。导入共享对象
  • 我不需要改变PYTHONPATH(尝试搞清楚并且失败了)。
  • 将来,分发项目包将是最简单的。
  • 目前的结构如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Project\

        docs\  # mainly documentation, right?

        bin\   # empty

        setup.py # setup for the project, as suggested in the above link

        project\  
            __init__.py
            module.py

            tests\
                 bla_test.py

        C\ # the package of C files
            file.c
            file.so
            other_c_stuff.c
            header.h
            setup.py # setup to compile the C files and create .so files
            build\ # contaisn a bunch of (hopefully) irrelevant stuf

    它适用于PyDev,但不适用于shell。理想的答案将解决以下问题:

  • 建议的项目结构。
  • 如何进行导入(例如,来自tests中的模块)。
  • 应该(可以)我将所有C文件保存在一个单独的库中吗?
  • C文件的构建是在setup.py文件中完成的(我应该在这里发布吗?)
  • 是否有可能在必要时自动构建?怎么样?
  • 我试过相对进口 - 由于某些原因它们不适合我。
    我看到了接受这个问题的答案。他说 - 做任何事。但我不能让进口工作。我读了这个答案,但不知道他有什么东西(我没有)。接受的答案对我没有帮助,因为再次进口失败了。这个博客文章提供了很好的建议,但再次,进口!


    我不想详细说明一般答案,因为你已经把它与好的答案挂钩了。

    一些适合你的结构可能看起来像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Project\

        build\ # directory used by setup.py

        docs\  # mainly documentation, right?

        setup.py # setup for the project, as suggested in the above link

        project\  
            __init__.py
            module.py

            c_package\
                __init__.py
                file.c
                file.so
                other_c_stuff.c
                header.h

            tests\
                __init__.py
                test_bla.py

    因此,如果您在适当的位置构建C Extensions,则在project包及其子包中可以使用相对导入

    1
    python setup.py build_ext --inplace

    或创建一个setup.cfg包含

    1
    2
    [build_ext]
    inplace=True

    但只能使用它进行开发而不释放它,因为安装将失败。

    构建自动化是可能的,但我不知道除了C源更改之外直接调用setup.py