繁体   English   中英

如何从不同目录正确运行 python 项目

[英]How can I run properly python project from different directory

python 项目文件层次结构:

parent/
    __init__.py
    one/
        __init__.py
        bar.py
    two/
       __init__.py
       foo.py

foo.py

from one import bar

我试图从其他目录(例如用户/用户)的终端运行 foo.py,我得到了下一个错误:

没有名为一个的模块

当我尝试运行 foo.py 时,我猜它正在尝试从执行代码的目录中导入文件,我尝试了很多方法,但我找不到解决方案,最后我找到了解决方案,这个解决方案的问题是这个解决方案并不优雅,我希望有一个优雅和更好的解决方案。

foo.py

from pathlib import Path
import sys

sys.path.append(str(Path(__file__).parent.parent))
sys.path.append("..")

from one import bar
  • 这个解决方案并不优雅,因为它阻止我将所有导入都放在页面的开头。

您在parent目录中有一个__init.py__的事实表明, parent目录是您的 package 结构的一部分,并且它的父目录(无论可能是什么)都应该在 PATH 中。 因此,您的导入实际上应该是:

from parent.one import bar

应用程序目录结构具有单个根可能很有用。 然后可以使用单根__init.py__中的 __init.py__ 从子包中加载模块,但这当然不是必需的。 如果这不是您的意图,那么您可能应该删除parent目录中的__init__.py ,因为它没有任何用途(并且令人困惑)并确保目录parent目录在您的 PATH 中。

但是:只要您在运行程序时所在的当前目录是 package 结构的根目录的父目录,Python 应该能够找到您的包而无需您采取任何特殊措施,因为当前目录会自动添加到路径中。 如果这不方便,您可以设置环境变量PYTHONPATH

因此,根据 package 结构的一部分来确定是否应该更改导入语句。 然后,您应该安排 Python 通过将当前目录、PYTHONPATH 或sys.path设置为所需目录来查找您的包——但只执行一次。 如果您必须设置sys.path ,我会在启动时在您的主程序中执行此操作,然后才需要包含任何内容:

如果foo.py是您的主程序,那么在程序的顶部我将拥有:

if __name__ == '__main__':
    from pathlib import Path
    import sys

    # if your import statement is: from parent.one import bar, then:
    sys.path.insert(0, str(Path(__file__).parent.parent))
    """
    # if your import statement is: from one import bar, then:
    sys.path.insert(0, str(Path(__file__).parent))
    """

为什么不通过创建路径字典让父级充当子级的路径提供者? 像这样:

class parent:
...
    def createPathDict(self):
        self.path_dict = {}
        self.path_dict ['parent'] = self.parentPath
        self.path_dict ['one'] = os.path.join(self.parentPath, 'one')
        self.path_dict ['two'] = os.path.join(self.parentPath, 'two')
        # self.path_dict ['three'] = …
        # ...

从孩子'两个'你导入字典是这样的(我假设你使用类):

class foo:

    def __init__(self, parent):
          self.parent = parent

    def addPathsToPythDirs(self):
         sys.path.insert(1, self.parent.path_dict ['one'])  # better
         # sys.path.insert(0, self.parent.path_dict [key])  
...

这样你就可以把你的导入保存在 foo.py

为什么使用 sys.path.append(path) 而不是 sys.path.insert(1, path)?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM