我正在编写一个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
layers/
__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
train.py需要导入neuralnet.py的神经网络类。
neuralnet.py需要导入layers / inlayer.py等。
(我更喜欢相对进口。)
我有一个不同的应用程序(classify.py)需要导入此模块。 我在哪里......
from neuralnet.neuralnet import neuralnet
我尝试了几种导入方法。 要么我得到一个错误(主要是像父母一样的奥术未导入)
1)运行train.py(这是神经网络模块的一部分)
from . import layer # In file neuralnet.py
SystemError: Parent module '' not loaded, cannot perform relative import
或
2)运行classify.py(在模块外部)。
from layer.inlayers import input_layer # In file neuralnet.py
ImportError: No module named 'layer'
我的导入在Python2中运行良好多年。我想知道Python3对我的期望是什么?我应该将train.py移动到我的模块之外(技术上它不是模块的一部分)吗?请提出最佳做法。
由于 勒凯什
答案 0 :(得分:3)
在Python 3中,禁止隐式相对导入,请参阅https://www.python.org/dev/peps/pep-0328/和https://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax:
相对导入的唯一可接受的语法来自。[模块] 导入名称。所有导入表单都不以。被解释为 绝对进口。 (PEP 0328)
from .stuff import Stuff
是显式相对导入,您应该"应该"尽可能使用,并且只要有可能,必须在Python 3中使用。前往https://stackoverflow.com/a/12173406/145400进行更深入的相关进口分析。
答案 1 :(得分:0)
相对导入用法已从python2更改为python3,
相对导入的唯一可接受语法是
from .[module] import name
。所有导入表单均不以开头。被解释为绝对进口。 (PEP 0328
)
Python的
-m
开关允许将模块作为脚本运行。当您运行位于包装内的模块时,相对导入无法正常进行。 Python 2.6修复程序为模块添加了__package__
属性。存在此属性时,相对导入将相对于此属性的值而不是__name__
属性。 (PEP 0366
)
SystemError: Parent module '' not loaded, cannot perform relative import
或
在Python3.5和更高版本中,当您获得ImportError: attempted relative import with no known parent package
您运行python neuralnet.py
并尝试导入from . import layers
,因为您的__package__
将是None
,并且PYTHONPATH将仅具有当前文件(而不是其父文件),因此找不到layer
。您可以运行以下模块:
python -m neuralnet.neuralnet
您的__package__
将是neuralnet
,因此您将能够导入其中的neuralnet
模块。
或者您可以执行以下解决方法:
将__init__.py
软件包中的neuralnet
更新为:
import os
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
然后运行脚本neuralnet.py
,以上几行会将neuralnet
目录添加到PYTHONPATH。
如果ImportError: No module named 'layer'
不是PYTHONPATH中的模块,则会得到layer
,因此安装或将其添加到PATH strong>使用
import sys
sys.path.append("/path/to/layer")
来自Guido(Python的作者)的部分消息:
...在2.4版中,我们引入了相对导入的前导点符号, 同时仍允许相对导入而没有前导点。在 2.5我们可以开始警告有关相对导入而没有前导点 (尽管这无疑会引起那些 需要与2.3一起使用的代码)。 在3.0中,我们可以取消模糊的导入。
多个点的用例应该很明显:在高度 结构化程序包,一个子程序包中的模块必须有一种方法 从同一父包的另一个子包进行相对导入。
剩下的问题仍然是确切的语法。一世 建议扩展from子句,以允许一个或多个点 点名,如果至少一个,则使点名可选 找到前导点。我建议不要更改最少导入。
示例:
from .foo import bar from .foo.bar import xxx from . import foobar as barfoo from ..foo.bar import * from ... import foobar, barfoo
将PEP改为:PEP-328