如何在一个包中从兄弟模块导入?

6

我的包结构如下:

myPackage
 -- __init__.py <-- empty
 -- signal.py
 -- plot.py

signal.py 包含:

from plot import plot_signal

def build_filter():
   ...

def other_function():
   plot_signal()

plot.py 包含:

from signal import build_filter

def plot_signal():
   ...

def other_function():
   build_filter()

我有一个脚本,使用这个包的内容,大概是这样的:

import myPackage as mp

mp.plot.plot_signal()

当我运行它时,出现了一个属性错误:模块“myPackage”没有“plot”属性
我不确定为什么它把plot称为属性,而它是我的包中的一个模块,或者为什么它把myPackage称为一个模块。
然后我尝试导入我的包并以不同的方式调用函数:
from myPackage import plot, signal

plot.plot_signal()

然而,现在我遇到了一个导入错误:cannot import name 'build_filter'。回溯引用了plot.py,在那里它尝试从兄弟模块导入build_filter()函数。
我想这与两个模块相互使用函数并递归地导入另一个模块有关。
应该如何正确组织这个包,使兄弟模块能够相互导入函数?

@matino:我将语言标签更改为"python-3.x",因为这似乎是OP使用的版本(python 2会产生不同的错误消息)。你为什么要把它改回"python"呢? - martineau
@martineau - 我认为这个问题与Python的所有版本有关,无论错误信息如何,但如果您想要恢复Python-3x,可以随意这样做。 - matino
@matino:你尝试在两个版本中都使用过你的解决方案吗? - martineau
@martineau - 是的,我做了。 - matino
这个回答是否解决了你的问题?如何在同一目录或子目录中导入类? - mkrieger1
1个回答

4
为了让 mp.plot.plot_signal() 起作用,您必须在 myPackage.__init__.py 中导入 plot。 另一件事是,在 plot.py 和 signal.py 中,您应该导入整个模块以避免循环导入:

signal.py:

import myPackage.plot

myPackage.plot.plot_signal()

plot.py

import myPackage.signal

myPackage.signal.build_filter()

您也可以在这3个文件中使用相对导入,但它只能在Python 3.x中工作:

signal.py:

from . import plot

plot.plot_signal()

plot.py

from . import signal

signal.build_filter()

完美,看起来可以了。有没有办法在这 3 个文件中使用相对导入,这样我就不需要手动指定包名了?(那是将来可能会更改的内容)。 - Simon

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