[英]Packaging python with circular imports
我仔細查看了以前的問題,以了解這種效果,但情況略有不同...
我有一個包含幾個python類的目錄,這些類在必要時在這里和那里互相導入。 我想開始將它們打包成較小的模塊,主要是出於組織目的。 程序包的中心組件設置了一個wsgi應用程序,然后其他模塊為其提供了功能(到目前為止,這種方法非常有效,因為我可以在將命令行輸入連接到Web應用程序之前在命令行上分別測試這些Mod。)
我了解提供__init__.py
模塊的工作方式,其命名空間以及何時釋放控件。 我遇到的麻煩是,在某些情況下,模塊會相互導入。
例如,我有一個JSONEncoder,它用作對json.dumps()
許多調用的cls
參數。幾乎在每個文件中都使用該類。 如果將其中一些模塊移動到包中的子目錄中,我將如何“上一層”導入json編碼器? 我是否需要在每個文件的PYTHONPATH上放置父目錄? 最好也給編碼器自己的目錄,並使用一個單獨的__init__.py文件嗎?
或者,我是否最好放一個函數來向下鑽取當前工作目錄下的所有目錄並將它們添加到路徑中呢?
當前包含所有代碼的主目錄本身並不打包...考慮到它們具有循環導入,將類像類遷移到子目錄的最佳方法是什么?
編輯:
為了澄清:
我一直在開發的主要工作目錄只是一個常規目錄,其中包含約十個.py文件,所有這些文件都包含名稱類似於其文件名的類。 目前,整個過程只是.py文件的git repo。
-project
search.py
jsonencoder.py
webapp.py
modela.py
modelb.py
modelc.py
名稱當然是出於示例目的。
現在,據我所知(這可能是完全錯誤的),明智的做法是將這些模型打包在一起,對嗎?
-project
search.py
jsonencoder.py
webapp.py
-models
__init__.py
modela.py
modelb.py
modelc.py
但是隨后, project
文件夾也需要__init__
嗎? 使用jsonencoder的modela如何導入它?
答案很簡單:
只需為您需要的子模塊使用完全限定的名稱
例如,在
mybundle/test/__init__.py
你可以排隊
import mybundle.JSONEncoder
例如,給定此模塊結構:
├── mybundle
│ ├── __init__.py
│ ├── jsonencoder
│ │ ├── __init__.py
│ └── test
│ ├── __init__.py
文件定義如下:
[gwidion@powerpuff tmp]$ cat mybundle/__init__.py
import test
[gwidion@powerpuff tmp]$ cat mybundle/test/__init__.py
import mybundle.jsonencoder
[gwidion@powerpuff tmp]$ cat mybundle/jsonencoder/__init__.py
print 5
這有效:
[gwidion@powerpuff tmp]$ python
Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16)
[GCC 4.6.0 20110331 (Red Hat 4.6.0-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mybundle
5
>>>
您可以嘗試如下操作( root
是您的工作目錄):
/root
- file_a.py
- file_b.py
/JSONEncoder
- __init__.py
- JSONEncoder.py
__init__.py
為空白,或具有pass
或注釋或其他內容。 然后,您可以執行以下操作(從file_a.py
或root
任何命令):
from JSONEncoder import JSONEncoder
並可以訪問JSONEncoder
中的file_a.py
。 只要您所有正在運行的代碼都位於/root
並且僅在子目錄中需要__init__.py
就無需觸摸PYTHONPATH
。 這種類型的目錄布局非常有用,因為您可以隱藏“正常工作”的代碼,並專注於需要處理的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.