我正在看看django中的模型系統是如何工作的,並且我注意到了一些我不明白的東西。將代碼添加到__init__.py
我知道你創建一個空的__init__.py
文件來指定當前目錄是一個包。並且您可以在__init__.py
中設置一些變量,以便導入*正常工作。
但是django增加了一大堆from ... import ...語句並在__init__.py
中定義了一堆類。爲什麼?這不就是讓事情看起來凌亂嗎?是否有一個原因需要__init__.py
中的代碼?
我正在看看django中的模型系統是如何工作的,並且我注意到了一些我不明白的東西。將代碼添加到__init__.py
我知道你創建一個空的__init__.py
文件來指定當前目錄是一個包。並且您可以在__init__.py
中設置一些變量,以便導入*正常工作。
但是django增加了一大堆from ... import ...語句並在__init__.py
中定義了一堆類。爲什麼?這不就是讓事情看起來凌亂嗎?是否有一個原因需要__init__.py
中的代碼?
當導入包含它的包(目錄)時,__init__.py
中的所有導入都可用。
例子:
./dir/__init__.py
:
import something
./test.py
:
import dir
# can now use dir.something
編輯:忘了提,在__init__.py
代碼運行你第一次從目錄中導入任何模塊。所以它通常是放置任何包級初始化代碼的好地方。編輯2:dgrant在我的例子中指出了可能的混淆。在__init__.py
import something
可以導入任何模塊,從包中不需要。例如,我們可以用import datetime
替換它,然後在我們的頂級test.py
這兩個片斷都可以工作:
import dir
print dir.datetime.datetime.now()
和
import dir.some_module_in_dir
print dir.datetime.datetime.now()
的底線是:在__init__.py
分配的所有名稱,是它導入的模塊,函數或類,只要在包中導入包或模塊,就會自動在包名稱空間中使用。
好的,謝謝。但我仍然不確定爲什麼將類添加到`__init __。py`中是一個好主意。我並沒有真正考慮這些類的初始化代碼(但也許我錯了)。 – Erik 2008-09-23 04:57:23
這些可能是每次使用包時都很有用的類。但我不想推測,可能有很多原因,爲什麼他們在那裏,客觀或沒有:) – 2008-09-23 05:08:11
這真的只是個人喜好,並且與你的python模塊的佈局有關。
假設您有一個名爲erikutils
的模塊。有兩種方法,它可以是一個模塊,要麼你有一個文件名爲erikutils.py您sys.path
或者你有一個叫做上的目錄sys.path
erikutils,內帶一個空__init__.py
文件。那麼假設您有一堆名爲fileutils
,procutils
,parseutils
的模塊,並且您希望這些模塊是erikutils
下的子模塊。所以,你做一些.py文件名爲fileutils.py,procutils.py和parseutils.py:
erikutils
__init__.py
fileutils.py
procutils.py
parseutils.py
也許你有,只是沒有在fileutils
屬於少數的功能, procutils
或parseutils
模塊。假設您不想創建名爲miscutils
的新模塊。而且,你希望能夠調用的函數,像這樣:
erikutils.foo()
erikutils.bar()
,而不是做
erikutils.miscutils.foo()
erikutils.miscutils.bar()
所以因爲erikutils
模塊是一個目錄,而不是一個文件,我們必須定義它的功能在__init__.py
文件中。
在django中,我能想到的最好例子是django.db.models.fields
。所有的django *字段類都是在__init__.py
文件中定義的django/db/models /字段目錄中。我猜他們這樣做是因爲他們不希望所有東西都塞進一個假設的Django/DB /模型/ fields.py模式,所以他們分裂出來成幾個子模塊(related.py,files.py例如),他們將製作的*字段定義粘貼在字段模塊本身中(因此,__init__.py
)。
使用__init__.py
文件可以讓您從外部看不到內部包裝結構。如果內部結構發生變化(例如,因爲您將一個胖模塊拆分爲兩個),則只需調整__init__.py
文件,而不是依賴於程序包的代碼。您還可以使您的包的某些部分不可見,例如如果他們沒有準備好一般用法。
注意,您可以使用del
命令,因此,典型__init__.py
可能是這樣的:
from somemodule import some_function1, some_function2, SomeObject
del somemodule
現在,如果你決定拆分somemodule
新__init__.py
可能是:
from somemodule1 import some_function1, some_function2
from somemodule2 import SomeObject
del somemodule1
del somemodule2
從包裝的外觀仍然與以前完全一樣。
這不是真的關於Django嗎?是的,你首先在Django中看到了它,但這看起來更像是一個純Python的東西 - 也許Django標籤並不合適。 – 2008-09-23 12:46:20
我在`__init __。py` django 1.8中看不到任何import語句。這是舊版本嗎?如果是的話哪個版本? – 2017-01-03 06:51:08