【问题标题】:The command `python setup.py build_ext --inplace` always create a new directory命令 `python setup.py build_ext --inplace` 总是创建一个新目录
【发布时间】:2015-08-06 05:35:51
【问题描述】:

假设我有一个结构如下的 python 包:

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx

setup.py的内容是

from distutils.core import setup
from Cython.Build import cythonize
import numpy as np

setup(
    ext_modules=cythonize("bar/bar.pyx"),
    include_dirs=[np.get_include()]
)

那我就跑

python setup.py build_ext --inplace

因为我需要将编译后的文件bar.so 准确地放在bar/ 中。但是前面的命令在bar下创建了一个新目录foo/bar/,然后把bar.so放在那里,比如说,

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx
    foo/
      bar/
        bar.so

而我需要的是

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx
    bar.so

这些烦人的事情发生在我把foobar变成一个包之后。如果我删除foo/__init__.pybar/__init__.py,那么bar.so 将出现在foo/ 中,但仍然不是foo/bar/。我已阅读手册,但没有找到解决此问题的选项。

如果我要求bar.so 出现在正确的位置,同时保留两个__init__.py 文件,我该怎么办?

【问题讨论】:

    标签: python python-2.7 cython setup.py


    【解决方案1】:

    setup.py 不应该存在于包中。您需要将包上移一个目录:

    foo/
      setup.py
      foo/
        __init__.py
        bar/
          __init__.py
          bar.pyx
    

    这是我遇到的大多数包所遵循的结构。


    至于 scikit-learn,你用它来获得灵感:

    我当然不知道 scikit-learn 对他们的多个 setup.py 文件做了什么,但我敢打赌,说外部 setup.py 正在使用(调用、导入)另一个 setup.py s,将子包配置的详细信息分发给setup.pys 个人。它只是不是很明显,因为(我认为)distutils/setuptools 在引擎盖下做了很多这种导入。

    因此,外部设置负责整个包,内部设置负责子包的细节。

    但最后,它仍然是另一层中的一个大setup.py 文件。尝试运行

    python setup.py build_ext --inplace
    

    在任何内部setup.pys 上,它要么失败,要么什么也不做(至少对于我给它的两次尝试)。

    因此,这些子包 setup.pys 可能更适合视为 setup_config.py 文件。

    作为一个有趣的结果,安装包会将这些setup.py 文件保留在它们各自的子包中(以及sklearn 中的那个)。也许在使用软件包时会有一些用处,但我想这只是 scikit-learn 设置过程的产物,并且包含所有 *.py 文件。

    【讨论】:

    • 其实我的目录结构是参考scikit-learn的。但你是对的,它应该有另一层。不过我还有一个问题:在scikit-learn 中,除了最外层的setup.py 之外,每个包都有自己的setup.py 旁边的__init__.py,这就是我将setup.py 放在一个包中的原因。内部setup.pys 是如何工作的?
    • @ludmofans 套用 Fermat 的话说:我对 scikit-learn 部分发表了评论,但它太长了,无法放入评论框中。我已经扩展了我的答案,这可能无法完全解释正在发生的事情,但希望能让您对 scikit-learn 正在做什么有一个很好的了解(注意:到目前为止,我不知道任何其他以这种方式做事的包)。
    • 是的,你是对的,我检查了scikit-learn 中的两个setup.pys,其中一个只是为放置它的子包设置了配置。另外,最外面的setup.py使用了一个叫delegate_options_to_subpackages的选项,我相信这就是诀窍。
    猜你喜欢
    • 2014-12-21
    • 2018-05-16
    • 1970-01-01
    • 2015-06-11
    • 2021-04-09
    • 2017-09-23
    • 2018-07-30
    • 2012-12-17
    相关资源
    最近更新 更多