首页 > 解决方案 > 在 Python 3.x 中导入时的问题

问题描述

我的问题可以总结如下。

我有以下文件结构:

<path>/
- a.py
<path>/subdir/
- b.py
- c.py

关系是 a 导入 b 和 b 导入 c (a->b->c)。

更准确地说,每个文件的内容如下:

def foo():
    print("Hello World!")
import c
def fie():
    c.foo()
    print("Second Hello World!")
if __name__=="__main__":
    fie()
from subdir import b
b.fie()

我想要的是调用 a.py 将打印这些字符串,即:

$ python3 a.py
Hello World!
Second Hello World!
$ 

并从 /subdir 调用 b.py 将打印相同的内容:

$ cd subdir
$ python3 b.py
Hello World!
Second Hello World!
$ 

相反,如果我调用 a.py<path>我有这个:

$ python3 a.py
Traceback (most recent call last):
  File "a.py", line 1, in <module>
    from subdir import b
  File "<path>/subdir/b.py", line 1, in <module>
    import c
ModuleNotFoundError: No module named 'c'
$ 

相反,如果我从<path>/subdir我有预期的行为调用 b.py:

$ cd subdir
$ python3 b.py
Hello World!
Second Hello World!
$ 

如果我通过以下方式更改 b.py :

from subdir import c
def fie():
    c.foo()
    print("Second Hello World!")
if __name__=="__main__":
    fie()

a.py 的调用按预期工作,但这次是 b.py 的调用,它给出ModuleNotFoundError

$ cd subdir
$ python3 b.py
Traceback (most recent call last):
  File "b.py", line 1, in <module>
    from subdir import c
ModuleNotFoundError: No module named 'subdir'
$ 

奇怪的是,即使这个调用 from<path>给出了同样的错误:

$ python3 subdir/b.py
Traceback (most recent call last):
  File "b.py", line 1, in <module>
    from subdir import c
ModuleNotFoundError: No module named 'subdir'
$ 

如果我在 b.py 中替换以下字符串:

from subdir import c

from . import c

我和上次测试的效果完全一样。

在实际情况下,b 和 c 都是子目录中自包含库的一部分,该库既可以直接使用(使用if __name__技巧),也可以从其他任何地方导入以使用它们的功能。目前无法将所述库安装在文件系统的固定空间中(或者至少我不应该依赖它)。

我在使用 Python 2.6 时从未遇到过这样的问题,而且我最近正在迁移到 Python 3.x。阅读 python 3.x 导入指南很有帮助,但我没有找到任何有用的信息来解决这个应该非常基本的案例(这就是为什么我认为我在那里省略了一些微不足道的东西)。

您能否建议一种方法来更改任何 [a,b,c].py 文件以涵盖此用例?

标签: pythonpython-3.x

解决方案


以下对我有用(至少在 Windows 下)。

addpath通过调用将您希望应用程序访问的目录(作为字符串)或目录(作为字符串列表)作为参数来启动您的主程序:

def addpath(dirs):
  import sys,os
  my_path = '/'.join(os.path.abspath(sys.argv[0]).replace('\\','/').split('/')[:-1])+'/'
  if type(dirs) is str:
    sys.path.append(my_path+dirs)
  elif type(dirs) is list:
    for dir in dirs:
      sys.path.append(my_path+dir)

################################################################################

addpath('subdir')  #or addpath(['subdir1',...])

from subdir import b
b.fie()

推荐阅读