简体   繁体   English

Python3导入出现问题

[英]Trouble with Python3 imports

This question was asked a lots of times but none of the solutions seem to help in my case. 这个问题被问了很多次,但是在我看来,所有解决方案都没有帮助。

I have a directory structure like this 我有这样的目录结构

my_project/
    main.py
    bootstrap/
        __init__.py
        boot.py
    consumer/
        __init__.py
        main.py

Being at the toplevel directory ( myproject ) and executing python3 consumer/main.py throws an error: 位于顶层目录( myproject )并执行python3 consumer/main.py会引发错误:

Traceback (most recent call last):
  File "consumer/main.py", line 7, in <module>
    from bootstrap.boot import MyClass
ImportError: No module named 'bootstrap'

Weird thing is that importing that module using the interpreter works as expected. 奇怪的是,使用解释器导入该模块的工作符合预期。 Running the code from PyCharm also works fine. 从PyCharm运行代码也可以正常工作。

I've tried importing with "full path" eg from my_project.bootstrap.boot import MyClass which fails with the same ImportError . 我尝试使用“完整路径”导入,例如from my_project.bootstrap.boot import MyClass ,失败,并出现相同的ImportError I have also tried using relative imports eg from .bootstrap.boot import MyClass which also failed with SystemError: Parent module '' not loaded, cannot perform relative import 我也尝试过使用相对导入,例如from .bootstrap.boot import MyClass ,它也失败,并出现SystemError: Parent module '' not loaded, cannot perform relative import

One hack that fixes this is when I add export PYTHONPATH="/root/my_project" at the bottom of virtualenv activate script 解决此问题的一种方法是在virtualenv activate脚本的底部添加export PYTHONPATH="/root/my_project"

You are getting this error because module search path only includes the current directory, and not its parents; 因为模块搜索路径仅包含当前目录,而不包含其父目录,所以您会收到此错误。 and since your other module is not in the PYTHONPATH it isn't available to import. 并且由于您的其他模块不在PYTHONPATH ,因此无法导入。

You can find this out yourself by printing sys.path in your script. 您可以通过在脚本中打印sys.path来自己找到。

I created a directory t with the following: 我使用以下命令创建了目录t

$ tree
.
├── a.py
├── bar
│   ├── __init__.py
│   └── world.py
└── foo
    ├── hello.py
    └── __init__.py

2 directories, 5 files

Here is the source of hello.py : 这是hello.py的来源:

$ cat foo/hello.py
import sys
print("I am in {}".format(__file__))
for path in sys.path:
    print(path)

from bar.world import var
print(var)

Now watch what happens, when I execute foo/hello.py and try to import something from bar/world.py ; 现在看发生什么,当我执行foo/hello.py并尝试从bar/world.py导入一些东西时;

$ python foo/hello.py
I am in foo/hello.py
/home/burhan/t/foo
/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/home/burhan/.local/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
Traceback (most recent call last):
  File "foo/hello.py", line 6, in <module>
    from bar.world import var
ImportError: No module named bar.world

You can tell from the paths printed that only the system-wide Python library paths, and the current directory of the script is listed. 从打印的路径中可以看出,仅列出了系统范围的Python库路径以及脚本的当前目录。 This is why it cannot find bar.world . 这就是为什么它找不到bar.world

To fix this issue, you can adjust the PYTHONPATH or use relative imports; 要解决此问题,您可以调整PYTHONPATH或使用相对导入。 for example: 例如:

$ PYTHONPATH=../t python foo/hello.py
I am in foo/hello.py
/home/burhan/t/foo
/home/burhan/t
/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/home/burhan/.local/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
42

You notice here I am manually overriding the PYTHONTPATH and adding the common parent of the scripts ( 42 is coming from bar/world). 您会在这里注意到,我正在手动覆盖PYTHONTPATH并添加脚本的公共父级( 42来自bar / world)。

To fix this using relative imports, you first have a to create a package in the top most directory, otherwise you'll get the famous Attempted relative import in non-package error; 要使用相对导入来解决此问题,您首先需要在最顶层的目录中创建一个包,否则您将得到著名的Attempted relative import in non-package错误。 for more on this and details on how Python 3 importing works, have a look at: Relative imports in Python 3 有关此内容的更多信息以及有关Python 3导入工作方式的详细信息,请查看: Python 3中的相对导入

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

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