我已经阅读了无数有关python相对导入的讨论,我认为它如此混乱的原因之一是它将一个Python版本更改为另一个版本(我的版本是3.6)。但是这里的罪魁祸首似乎是PyCharm(除非我误会了..),我想知道是否有人遇到过此问题的解决方案。对于具有这种布局的项目:
/project
|-- __init__.py
|---subfolder
|-- __init__.py
|-- AA.py
|-- BB.py
Run Code Online (Sandbox Code Playgroud)
让我们想象一下,如果我编写此导入myfunc
文件,AA.py 在文件中包含一些功能BB.py:
from AA import myfunc
Run Code Online (Sandbox Code Playgroud)
那么Python的作品完美,但PyCharm认为这是一个错误:

因此,为了使PyCharm满意,我可以将y添加.到导入中,然后看似已解决了该错误:
from .AA import myfunc
Run Code Online (Sandbox Code Playgroud)
但后来python不高兴,给了我错误: ModuleNotFoundError: No module named '__main__.AA'; '__main__' is not a package
因此,总而言之,我使用的是实际有效的导入(即from AA import myfunc),但是如果我可以使PyCharm对此表示同意,那将是非常不错的,因为这样它就提供了诸如自动完成,定义等功能。
不是重复的: 我知道似乎这个主题已经被反复讨论了,但是它也有很多方面。在这里我谈论的是pycharm方面,因此据我所知这个主题是新的。
我的脚本无法运行,我有一些非常神秘的行为.显然,下面的脚本是微不足道的,什么都不做,但它是在一个真实的脚本中再现行为.这是调用文件中的代码test.py.
import os
os.chdir('/home/jacob/twcSite')
import app
Run Code Online (Sandbox Code Playgroud)
app位于'home/jacob/twcSite',与当前目录不同的目录,包含test.py.如果我python test.py在命令行键入,我得到ImportError: No module named app.但是,如果我只是键入python以启动交互式解释器并复制粘贴完全相同的三个命令,那么它可以正常工作而不会导致导入错误.
什么可能导致此错误?这是python的相同版本.完全相同的代码行.为什么我在两种情况下都会有不同的行为?只是为了给出更多的细节,如果你os.getcwd()在调用os.chdir它之前和之后打印输出确实声称已经改变到正确的目录(尽管显然不是这种情况).我正在运行Ubuntu 14.04,Python版本2.7.6.
我具有以下文件夹结构:
app
__init__.pyutils
__init__.pytransform.pyproducts
__init__.pyfish.py在fish.py中,我transform按以下方式导入:import utils.transform。
当我从Pycharm运行fish.py时,它运行得很好。但是,当我从终端运行fish.py时,出现了error ModuleNotFoundError: No module named 'utils'。
我在终端中使用的命令:来自app文件夹python products/fish.py。
我已经研究了这里建议的解决方案:从不同的文件夹导入文件,将应用程序文件夹的路径添加到sys.path帮助中。但是我想知道是否还有其他方法可以使它工作而无需向中添加两行代码fish.py。这是因为我在/ products目录中有很多脚本,并且不想在其中每个脚本中添加两行代码。
我研究了一些开源项目,并且看到了很多示例,这些示例是从并行文件夹中导入模块而不向sys.path中添加任何内容的,例如:https : //github.com/jakubroztocil/httpie/blob/master/httpie/plugins /builtin.py#L5
如何以相同的方式使其适用于我的项目?
我是 pytest 和 python 的新手。我的项目结构是:
projroot/
|-src/
|-a.py
|-test/
|-test_a.py
Run Code Online (Sandbox Code Playgroud)
而 test_a.py 是:
projroot/
|-src/
|-a.py
|-test/
|-test_a.py
Run Code Online (Sandbox Code Playgroud)
然后在pytest以下运行projroot:
projroot>pytest
Run Code Online (Sandbox Code Playgroud)
并且总是有错误信息:E ImportError: attempted relative import with no known parent package。Python 版本:Windows 10 x64 上的 3.8。我阅读了很多文章和博客以及官方建议,但仍然没有弄清楚。请帮帮我!
我正在编写一个 python 模块neuralnet。它在 Python2 中一切正常,但在 Python3 中导入失败。
这是我的代码结构。
neuralnet/
__init__.py
train.py # A wrapper to train (does not define new things)
neuralnet.py # Defines the workhorse class neuralnet
layer/
__init__.py
inlayer.py # Defines input layer class
hiddenlayer.py
application/ # A seperate application (not part of the package)
classify.py # Imports the neuralnet class from neuralnet.py
Run Code Online (Sandbox Code Playgroud)
train.py需要导入neuralnet.py 的neuralnet类。
neuralnet.py需要导入layers/inlayer.py等
(我更喜欢相对进口。)
我有一个不同的应用程序 ( classify.py) 需要导入这个模块。我在哪里...
from neuralnet.neuralnet import neuralnet
Run Code Online (Sandbox Code Playgroud)
我尝试了几种导入方式。要么我得到一个错误(主要是像 parent 这样的神秘未导入)
运行 …
可以使用在路径中引用两个以上点的模块吗?像这个例子:
# Project structure:
# sound
# __init__.py
# codecs
# __init__.py
# echo
# __init__.py
# nix
# __init__.py
# way1.py
# way2.py
# way2.py source code
from .way1 import echo_way1
from ...codecs import cool_codec
# Do something with echo_way1 and cool_codec.
Run Code Online (Sandbox Code Playgroud)
UPD:更改了示例。我知道,这将在实践中起作用。但这是一种常见的导入方法吗?
让我总结一下:
我有一个包含两个类的模块(注意:该模块位于一个包中):
自定义异常:
class MYAUTHError(Exception):
def __init__(self, *args, **kwargs):
print('--- MYAUTHError!!! ---')
Run Code Online (Sandbox Code Playgroud)
和一个使用此异常的类(这里是一个示例):
try:
resp_login.raise_for_status()
except requests.exceptions.HTTPError as ex:
logging.error("ERROR!!! : user authentication failed)
raise MYAUTHError('oups')
Run Code Online (Sandbox Code Playgroud)
在这个模块(文件)内我知道这是有效的。例如,我可以编写这样的代码并验证是否捕获了我的自定义异常:
try:
raise MYAUTHError('oups')
except MYAUTHError:
print("got it")
Run Code Online (Sandbox Code Playgroud)
但是,当从另一个模块(导入此模块的模块)使用时,我没有成功捕获此自定义异常......
from mypackage import mymodulewithexception
# somewhere in the code, just to test. OK : my class is known.
extest = mymodulewithexception.MYAUTHError('**-test-**')
print(type(extest))
# but this does not catch anything :
except mymodulewithexception.MYAUTHError as ex:
logging.error("Authentication failed", ex)
return
Run Code Online (Sandbox Code Playgroud)
我确信,异常被抛出,因为调用模块是一个 Flask 应用程序,并且调试服务器清楚地向我显示异常被抛出,因为它没有被处理。
在试图理解这一点时,我只是用另一个著名的异常替换了我的自定义异常:ValueError。我更改了调用模块中的代码以捕获此内容:当然,这有效。
我什至尝试捕获异常(真正的通用类):
except mymodulewithexception.MYAUTHError …Run Code Online (Sandbox Code Playgroud) 我有一个项目要结构如下:
myproject
__init__.py
api
__init__.py
api.py
backend
__init__.py
backend.py
models
__init__.py
some_model.py
Run Code Online (Sandbox Code Playgroud)
现在,我想同时在api.py和backend.py中导入some_model.py模块。如何正确执行此操作?我试过了
from models import some_model
Run Code Online (Sandbox Code Playgroud)
但是失败并显示为“ ModuleNotFoundError:没有名为'models'的模块”。我也试过
from ..models import some_model
Run Code Online (Sandbox Code Playgroud)
然后给我“ ValueError:尝试相对顶级包进行相对导入”。我在这里做错了什么?如何从其他目录(不是子目录)导入文件?
我将所有 pytest 文件存储tests在项目根目录下的子目录中。__init__.py该目录或以上目录中没有pytest tests/test_a.py并按预期工作。我也可以pytest test_a.py直接从tests文件夹中运行。
|--<project_root>
+---[tests]
test_a.py
base.py
config.py
conftest.py
Run Code Online (Sandbox Code Playgroud)
中的测试类test_a.py继承自base.py. 现在的问题是,由于缺少__init__.pyIDE 工具,因此无法解决导入问题。添加__init__.py在testsIDE 中解决了所有导入错误,但测试将不再运行,pytest test_a.py因为 py.test 无法导入conftest.py。
在我的conftest.py我有以下进口:
from config import HOST_URL_DEFAULT, USER, PASSWORD
Run Code Online (Sandbox Code Playgroud)
这导致:
ModuleNotFoundError: No module named 'config'
ERROR: could not load /project_root/tests/conftest.py
Run Code Online (Sandbox Code Playgroud)
有没有办法解决这个问题,这样两个 IDE 工具都可以工作并 pytest继续工作?如果可能,我想避免使用点导入。
更新:阅读此答案后,我想我终于开始更多地了解 python 导入的工作原理了。
我正在制作一个包,这个包中的模块在if __name__=='__main__':块中包含用于测试目的的代码。但是我尝试在这些模块中使用相对导入会导致错误。
我已经阅读了这个帖子和其他十亿人: 第 10 亿次的相对进口
在将其标记为重复之前,如果我想做的事情在 Python3 中是不可能的,那么我的问题是为什么它可以在 Python2 中工作,以及是什么促使决定在 Python3 中如此麻烦?
这是我的示例 Python 项目:
mypackage
- module1.py
- module2.py
- __init__.py
Run Code Online (Sandbox Code Playgroud)
__init__.py并且module2.py是空的
module1.py 包含:
import module2
# module1 contents
if __name__=="__main__":
# Some test cases for the contents of this module
pass
Run Code Online (Sandbox Code Playgroud)
这在 Python2 中工作正常。我可以从我计算机上任何位置的其他项目导入 module1,我也可以直接运行 module1 并if运行块中的代码。
但是,这种结构在 Python3 中不起作用。如果我尝试在其他地方导入模块,它会失败:
>>> from mypackage import module1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\_MyFiles\Programming\Python Modules\mypackage\module1.py", line …Run Code Online (Sandbox Code Playgroud) python relative-path python-import python-3.x python-packaging
python ×9
python-3.x ×4
import ×2
pycharm ×2
pytest ×2
coding-style ×1
exception ×1
package ×1
python-2.7 ×1
python-3.4 ×1