2017-09-16 72 views
0

我使用PyCharm和Python 3,我有下一個文件夾蟒佈局:舉止怪異(僅大寫的工作,不能與親人)Python的進口

src/ 
    __init__.py 
    command/ 
     __init__.py 
     simpleremote/ 
      __init__.py 
      Command.py 
      GarageDoor.py 
      GarageDoorOpenCommand.py 
      Light.py 
      LightOffCommand.py 
      LightOnCommand.py 
      RemoteControlTest.py 
      SimpleRemoteControl.py 

我創建的包,你可以看到。與main方法的文件是RemoteControlTest.py與這些進口的工作完美:

from pythonDesignPatterns.src.command.simpleremote.GarageDoor import GarageDoor 
from pythonDesignPatterns.src.command.simpleremote.GarageDoorOpenCommand import GarageDoorOpenCommand 
from pythonDesignPatterns.src.command.simpleremote.Light import Light 
from pythonDesignPatterns.src.command.simpleremote.command import LightOnCommand 
from pythonDesignPatterns.src.command.simpleremote.SimpleRemoteControl import SimpleRemoteControl 

上創建初始化的包.py文件,我試圖用相對進口,而不是以前的人,例如

from .command import LightOnCommand 

,但它給了我一個錯誤(將稱之爲情況A):

​​

所以擺弄周圍,我發現,這個工作對於同一行:

from command.simpleremote.Command import LightOnCommand 

和程序成功地再次執行,但如果我用的是「重構」選項從IDE(PyCharm)和重命名「命令「到 」命令「,寫這行:

from command.simpleremote.command import LightOnCommand 

突然顯示錯誤(情況B):

ImportError: No module named 'command.simpleremote'; 'command' is not a package 

在每種情況下(A和B)哪個是問題?我不明白爲什麼它會在從command.simpleremote導入的每個案例之間起作用。爲什麼沒有一個級別越來越靠近?爲什麼它使用大寫'C'而不是'c'?這是否區分大小寫?

我看過官方的Python文檔(和PEP302,PEP328和PEP420的網頁),但對於我來說這太複雜了。任何人都可以通過一種更簡單的方式來理解它(或者告訴我一個我可以閱讀的關於這個簡單解釋的資源)?

在此先感謝

回答

1

我猜你直接運行RemoteControlTest.py

情況A

Python的進口商不能去父母如果模塊作爲腳本直接運行它獲得通過封裝結構去代替。

Python的設計者大概不想讓子模塊直接作爲腳本調用,所以沒有真正的好解決方案。主要可以

  1. 運行與python -m command.simpleremote.RemoteControlTest腳本時src要麼是當前目錄或PYTHONPATH
  2. 使用一個測試框架,它確實在呼喚你。

有關可能的解決方案的更詳細的討論可以在Relative imports in Python 3找到。

情況B

直接啓動的一個後果是, 「src/command/simpleremote」 是module search path。 「src」似乎也被添加到路徑中,但在「src/command/simpleremote」之後。

from command...情況B之前的進口機制沒有找到「command」,在「src/command/simpleremote」匹配,繼續尋找在「src」裏被發現command包 - >成功。

如果B發現command.py在「src/command/simpleremote」這不是一個包 - >錯誤。

+0

關於答:對於相對導入並且通過包結構是不夠的將__init__.py文件放在每個文件夾中? 關於B:我在閱讀關於模塊搜索路徑鏈接來測試這一點。 PyCharm做了一個我認爲可能相關的sys.path.exy.tend。 – madtyn

+0

@madtyn關於A:不,對於直接啓動的腳本例如'__package__'屬性是空的。如果模塊通過包加載,'__package__'包含包名稱。 –

+0

我一直在閱讀這些日子。 Python文檔和PEP366,它推薦了一個雙線工作。我已經嘗試了'__package__'中的幾個值,但始終顯示'父模塊'package.value'未加載,無法執行相對導入 ' – madtyn