2013-07-01 37 views
3

我正在使用Python 3.3.2編寫封裝文件系統的包。我的項目如下所示:Python包設計和循環導入

~/ 
    python/ 
    filesystem/ 
     __init__.py 
     file.py 
     directory.py 

With PYTHONPATH=~/python

的問題是,需要file.pydirectory.py(例如,用於File.get_directory())和directory.py需要file.py(例如,用於Directory.get_files()),所以我具有圓形進口。

  1. 當我使用file.pyimport directory,並在import filedirectory.py,它只有當我的工作目錄是filesystem工程(即當進口本地)。
  2. 當我使用file.pyimport filesystem.directory,和import filesystem.filedirectory.py,它工作正常,但寫filesystem.file.File的審美滋擾及filesystem.Directory.directory全部時間。
  3. 奇怪的是,當我使用import filesystem.directory as directoryfrom filesystem.directory import Directory時,我得到了循環導入錯誤'module' object has no attribute 'directory'。我的猜測是,雖然import ...是懶惰的,但import ... asfrom ... import試圖評估模塊並立即注意到圓度。
  4. 解決此問題的一種方法是使用它的函數內部的import filesystem.directory。不幸的是,我的許多方法都使用它,並且在類中導入它似乎不起作用。

這當然是可以解決的:吸起來寫filesystem.directory.Directory;將__import__分配給__init__方法中的全局變量以供所有其他方法使用;在同一文件中定義FileDirectory;等等。但這些都比解決方案更妥協,所以我的問題仍然存在:所以我的問題仍然存在:

  1. 如何設計文件系統,其中文件類使用目錄類,反之亦然?
  2. 更一般地說,你將如何處理(或避免)循環進口?

謝謝。

UPDATE [2013年3月7日](大多爲討論的緣故)

另一種解決方案我來到是某種前向聲明的,與空filedirectory類在一個共同的報頭,接着分開實現(更像屬性添加)。雖然最終的設計非常整潔,但這個想法更多的是C++ - 而不是Pythonic。

+0

處理循環進口花了我一段時間。我真的必須將我的模塊(手動)繪製成樹形結構,確保我只向一個方向運送我的依賴關係。一旦我在做出更大的項目決策之前開始這樣做,它確實減少了我稍後必須做的重構。 – BlackVegetable

+0

@BlackVegetable - 你將如何設計沒有循環導入的描述文件系統?它看起來固有地是循環的,所以我很樂意聽到一些外部的替代設計。 –

回答

1

使用完全合格的路徑並不是真正的黑客行爲;這可能是解決這個問題的適當方法。如果你想有一個較短的名稱鍵入出來,你可以做這樣的事情:

import filesystem.directory 

class File(object): 

    def __init__(self): 
     self._Directory = filesystem.directory.Directory 

    def foo(self): 
     some_dir = self._Directory(...) 

這也可以輕鬆地將在模擬交換,如果你正在測試,等等。

+0

感謝您的回答。 這些基本上是「吸取它並寫入'filesystem.directory.Directory'」和「將__import__'分配給'__init__'方法中的全局變量,以便所有其他方法使用」解決方案,我猜完全合格的路徑確實是正確的解決方案,但我仍然在尋找替代品,即使只是出於學術好奇。 –