【问题标题】:Why 'setup.py develop' allow to import directories without '__init__.py'?为什么 'setup.py develop' 允许导入没有 '__init__.py' 的目录?
【发布时间】:2018-02-06 23:18:27
【问题描述】:

我正在做一个看起来像这样的简单项目:

\setup.py
\abcd
\abcd\__init__.py
\abcd\history\docs.py

当我针对我的 venv 运行 setup.py develop 时,import abcd.history 有效。当我针对我的 venv 运行 setup.py install 时,import abcd.history 返回一个异常:

ImportError: No module named 'abcd.history'

为什么? Python版本是3.5.1

【问题讨论】:

    标签: python setuptools


    【解决方案1】:
    $ ls -R1
    sub
    test-sub.py
    
    ./sub:
    __init__.py
    module
    
    ./sub/module:
    testxxx.py
    
    $ cat test-sub.py 
    #! /usr/bin/env python
    import sub.module
    
    $ python3.5 test-sub.py 
    $ python3.4 test-sub.py 
    $ python2.7 test-sub.py 
    Traceback (most recent call last):
      File "test-sub.py", line 3, in <module>
        import sub.module
    ImportError: No module named module
    

    简历:Python 3 可以在没有__init__.py 的情况下导入子模块(只有模块的顶级目录需要__init__.py),Python 2 不能。尝试找出 Python 2 在哪些地方让您的安装变得脆弱和瘫痪。

    【讨论】:

      【解决方案2】:

      setup.py develop 将你的包作为sort of a pseudo-symlink 安装到你的开发目录中,所以像\abcd\history\ 这样的东西在那里可见。 import abcd.history 然后将该文件夹导入为 implicit namespace package,这是 Python 3.3 中引入的功能。隐式命名空间包不需要__init__.py

      setup.py install 不会创建伪符号链接。它只安装它被配置为安装的东西,显然,它没有被配置为安装abcd.history

      【讨论】:

      • setup.py install 确实不会将 abcd\history 目录复制到 venv 中。 venv 中的 Egg 文件仅包含 \abcd\__init__.py
      【解决方案3】:

      来自docs

      需要 __init__.py 文件才能使 Python 将目录视为包含包;这样做是为了防止具有通用名称(例如字符串)的目录无意中隐藏模块搜索路径中稍后出现的有效模块。

      setup.py develop 只是将您的解释器指向允许导入 abcd.history 的本地目录,当您尝试将其实际 install 导入环境时失败。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-13
        • 2018-10-09
        • 2014-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多