特定于应用程序的 PYTHONPATH

Mik*_*att 5 python pythonpath sys.path

我有一个具有包层次结构的应用程序。有相当多的模块引用了包层次结构中更高的其他模块。如下所示,我可以使用相对导入来解决这个问题。但是,直接运行模块进行测试会失败并出现Attempted relative import in non-package异常。

有没有更好的方法来组织我的应用程序或我的导入语句,以便模块可以单独执行以进行测试并从其他模块导入?

例子

\spam
    \morespam
        child.py
    base.py
\eggs
    user.py
Run Code Online (Sandbox Code Playgroud)

基础文件

class Base(object):
    def hello(self):
        print 'Um, wot?'
Run Code Online (Sandbox Code Playgroud)

孩子.py

from ..base import Base       # references the parent package correctly, 
                              # but fails when this module is executed individually

class Child(Base):
    def hello(self):
        print 'Hello, world!'

if __name__ == '__main__':
    import unittest
    # ... unit test code ...
Run Code Online (Sandbox Code Playgroud)

用户.py

from spam.morespam.child import Child
print Child().hello()
Run Code Online (Sandbox Code Playgroud)

现有解决方案

我发现我可以将以下标题添加到需要引用层次结构中更高模块的模块的顶部:

if __name__ == '__main__':
    import sys, os
    sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..')))
Run Code Online (Sandbox Code Playgroud)

缺点是我需要到处添加此代码,并且它不是恒定的:'..'相对路径根据层次结构中包的深度而变化。

其他可能的解决方案...

  1. 我可以用我的应用程序根创建一个 .pth 文件。不幸的是,这必须添加到我的 Python 安装的 site-packages 文件夹中,因此它不是特定于应用程序的。
  2. 我可以临时将我的应用程序根添加到 PYTHONPATH,并使我的所有模块从根引用包。但是,这消除了通过简单地调用运行脚本的简单性python.exe whatever.py
  3. 我可以编写某种模块,当导入时,它会在我的应用程序的根文件夹中查找标记文件。然后可以将这个通用模块安装到我的本地 Python 安装中,并由我的应用程序中的每个模块导入,从而保证根在 PYTHONPATH 中,无论我正在执行哪个模块。

Mik*_*att 1

我用 PyCharm 解决了这个问题,每次运行我的应用程序时,它都会自动将我的源根目录添加到 PYTHONPATH 中。据我所知,PyCharm 基本上为我做了选项#2。