【问题标题】:Use __init__.py to modify sys path is a good idea?使用 __init__.py 修改 sys 路径是个好主意吗?
【发布时间】:2019-03-02 04:18:58
【问题描述】:

我想问你一些我想到的事情。

我有以下结构:

src
    - __init__.py
    - class1.py
    + folder2
        - __init__.py
        - class2.py

我 class2.py 我想导入 class1 来使用它。显然,我不能使用

from src.class1 import Class1

因为它会产生错误。对我有用的解决方法是在__init__.py 内的folder2 中定义以下内容:

import sys
sys.path.append('src')

我的问题是这个选项是否有效并且是一个好主意,或者是否有更好的解决方案。

另一个问题。想象一下项目结构是:

src
    - __init__.py
    - class1.py
    + folder2
        - __init__.py
        - class2.py
    + errorsFolder
        - __init__.py
        - errors.py

class1:

from errorsFolder.errors import Errors

这很好用。但是,如果我尝试在与errorsFolder 处于同一级别的class2 中进行操作:

from src.errorsFolder.errors import Errors

失败了 (ImportError: No module named src.errorsFolder.errors)

提前谢谢你!

【问题讨论】:

    标签: python python-import pythonpath


    【解决方案1】:

    解决此问题的一种正确方法是将环境变量PYTHONPATH 设置为包含src 的路径。那么import src.class1 将始终有效,无论您从哪个目录开始。

    【讨论】:

      【解决方案2】:

      from ..class1 import Class1 应该可以工作(至少它在类似的布局中使用 python 2.7.x)。

      作为一般规则:弄乱sys.path 通常是一个非常的坏主意,特别是如果这允许从两个不同的路径导入相同的模块(您的文件就是这种情况)布局)。

      此外,您可能需要对当前的布局三思而后行。 Python 不是 Java,不需要(甚至不鼓励)“每个模块一个类”的方法。如果两个类需要一起工作,它们可能在同一个模块中更好,或者至少在包树中同一级别的模块中更好(注意你可以使用顶级包的@987654323 @ 作为门面提供对子模块/子包中定义的对象的直接访问)。注意:我并不是说您当前的布局一定是错误的,只是它可能不是最简单的。

      【讨论】:

        【解决方案3】:

        不,这不好。 Python 以两种方式获取模块:

        1. Python 在 $PYTHONPATH 中查找它的模块和包。 参考:https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

        要找出 $PYTHONPATH 中包含的内容,请在 python (3) 中运行以下代码:

        import sys print(sys.path)

        1. 所有包含 init.py 的文件夹都被标记为 python 包。(如果它们是 PYTHONPATH 下的子目录)

        通过这两种方式,您可以完全满足创建python项目的需要。

        【讨论】:

          【解决方案4】:

          尽管必须在包中导入“父”模块有点令人震惊,但您的解决方法取决于您正在运行应用程序的当前目录,这很糟糕。

          import sys
          sys.path.append('src')
          

          应该是

          import sys,os
          sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),os.pardir))
          

          添加当前模块目录的父目录,无论您运行应用程序的当前目录是什么(您的模块可能由多个应用程序导入,它们并不都需要在同一个应用程序中运行目录)

          【讨论】:

            【解决方案5】:

            还有一个解决方案涉及使用环境变量 PYTHONPATH。

            src/ 中使用这些内容创建setup.py

            from setuptools import setup
            setup()
            

            现在您可以使用pip install -e /path/to/src 并导入您心中的内容。

            -e, --editable <path/url>   Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-09
              • 1970-01-01
              • 2010-11-05
              • 1970-01-01
              相关资源
              最近更新 更多