在PyCharm中的子包和相对导入

4

我正在使用Python 2:

python --version
Python 2.7.13 :: Continuum Analytics, Inc.

我的项目结构如下:

.
└── foo
    ├── bar1
    │   ├── __init__.py
    │   └── mod1.py
    ├── bar2
    │   ├── __init__.py
    │   └── mod2.py
    ├── __init__.py
    └── start.py

start.py

from foo.bar2.mod2 import mod2_f
mod2_f()

mod1.py

def mod1_f():
    print "mod1_f"

mod2.py

from foo.bar1.mod1 import mod1_f

def mod2_f():
    mod1_f()
    print "mod2_f"

如果我从IDE运行start.py,一切都正常。

但是使用类似这样的东西:

python ./foo/start.py

结果在
Traceback (most recent call last):
  File "./foo/start.py", line 1, in <module>
    from foo.bar2.mod2 import mod2_f
ImportError: No module named foo.bar2.mod2

现在,假设我将导入更改为

start.py

from bar2.mod2 import mod2_f
mod2_f()

mod2.py

from bar1.mod1 import mod1_f

def mod2_f():
    mod1_f()
    print "mod2_f"

现在可以通过命令行运行 python ./foo/start,但是PyCharm报错了。为什么会有这些差异?

好的,我目前没有使用Python 3,而是在使用Python 2。 - Juan Leni
1
我会说这是预期的:应该是 from bar2.mod2 import mod2_f - Jean-François Fabre
我已经尝试过了,但没有解决它。 - Juan Leni
请修改您的问题以显示为什么此解决方案不起作用。鉴于您提供的清晰项目结构,它“应该”可以工作。当然,由于更改了名称,可能存在拼写错误的可能性。但是现在您知道它“应该”可以工作,我相信您会让它工作的。 - Jean-François Fabre
如果它不起作用,可能是因为你正在使用Python 3,而你认为你正在使用Python 2 :) - Jean-François Fabre
PyCharm 可能已配置为在 Python 3 上运行。请检查 PyCharm 的内部 Python 引擎。我们以前就遇到过这种问题,当时 PyCharm 和独立安装的 Python 2.7 一起使用时也出现了类似的问题。 - Jean-François Fabre
1个回答

2

foo是一个包含所有内容的目录,包括start.py

因此,当你在start.py中执行以下操作时

from foo.bar2.mod2 import mod2_f

Python寻找名为foo的模块(因为它包含__init__.py,所以foo是一个模块),但是该模块位于您目录结构中过高的位置。我猜它在IDE中能够工作是因为IDE将每个模块目录都添加到了pythonpath中。但是如果从命令行运行,则无法工作。

简单的解决方法是,因为bar2start.py处于同一级别的目录中,所以可以:

from bar2.mod2 import mod2_f

请注意,在Python 3中,from的使用方式有所不同。请参考Python 3上的ImportError,在Python 2.7上工作正常,这可能是PyCharm在修复导入行时发出警告的原因。您应该配置PyCharm以使用Python 2而不是Python 3才能使其正常工作,或者完全放弃from语法并执行以下操作:
import bar2.mod2.mod2_f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接