2017-04-27 54 views
2

我的包結構如下:如何從包中的兄弟模塊導入?

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() 

當我運行此我得到一個屬性錯誤:module 'myPackage' has no attribute 'plot'

我不知道爲什麼它指的是plot作爲一個屬性當它在我的包的模塊,或者爲什麼它指myPackage作爲一個模塊。

然後我試圖導入我的包,並調用函數以不同的方式:

from myPackage import plot, signal 

plot.plot_signal() 

不過,現在我得到一個導入錯誤:cannot import name 'build_filter'和追溯是指plot.py哪裏它試圖導入build_filter()功能來自兄弟模塊。

我在想這與2個模塊使用另一個函數並遞歸導入另一個模塊的事實有關。

什麼是正確的方式來組織這個軟件包,以便兄弟模塊可以相互導入功能?

+0

@matino:我改變了語言標籤 「中的python-3.x的」,因爲這是在OP顯然是使用(Python 2裏產生不同的錯誤消息)。你爲什麼把它放回「蟒蛇」? – martineau

+0

@martineau - 我認爲這個問題與所有版本的python有關,不管錯誤信息如何,但隨時可以恢復python-3x。 – matino

+0

@matino:你有沒有在兩個版本中試過你的解決方案? – martineau

回答

2

要使mp.plot.plot_signal()工作,您必須在myPackage.__init__.pyimport 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() 
+0

完美,這似乎工作。有沒有辦法在這3個文件中使用相對導入,所以我不需要手動指定包名?(多數民衆贊成在某些時候可能會改變) – Simon

+0

是的,你可以,看我的編輯 – matino