在 __init__.py 裡寫程式碼的若干理由
阿新 • • 發佈:2019-01-31
在看庫或框架的開源原始碼時經常看到 __init__.py 裡留下了若干程式碼。__init__.py 檔案讓python認為init所在的資料夾是一個包,這自不必詳說。
當將一個包作為模組匯入時,實際上匯入了它的 __init__.py 檔案。
當我們匯入init包的時候,init指令碼自動執行。
那麼,為什麼要在 __init__.py 檔案裡寫程式碼,這樣做有什麼好處。
好處:在 __init__.py 裡寫一些程式內部用到的資料結構或為使用者提供一個統一的介面。
例如:
以 django forms 模組為例,在django.forms 模組裡定義了各種各樣的函式和類,這些函式和類分類放在不同的檔案中。
forms/
__init__.py
extras/
...
fields.py
forms.py
widgets.py
...
現在你要寫一個新 form ,必須繼承 Form 類,在 __init__.py 沒發揮作用時的程式碼是這樣的:
class CommentForm(forms.forms.Form): name = forms.fields.CharField() url = forms.fields.URLField() comment = forms.fields.CharField(widget=forms.widgets.Textarea)
這樣既不方便又很醜。而我們一般直接使用的是 django.forms 包下的 namespace。像這樣:
from django import forms
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
這就是在 forms/__init__.py 裡寫程式碼的好處(可以引入 widgets, forms, fields)from django.forms.fields import * from django.forms.forms import * from django.forms.formsets import * from django.forms.models import * from django.forms.widgets import *
例2:
有這樣一個foo包
foo/
__init__.py
foofactories.py
tallFoos.py
shortfoos.py
mediumfoos.py
santaslittlehelperfoo.py
superawsomefoo.py
anotherfoo.py
在init腳本里這樣寫:
__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos',
'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo']
# deprecated to keep older scripts who import this from breaking
from foo.foofactories import fooFactory
from foo.tallfoos import tallFoo
from foo.shortfoos import shortFoo
如此做,則可以在別的腳本里簡單方便的寫:
from foo import fooFactory, tallFoo, shortFoo
簡化了程式碼量。
若 from foo import * ,則匯入了init裡的 __all__ 變數裡註冊的所有模組(不推薦)
Django 經常把一些共通的類或函式放在 init 裡,例如 django.conf.urls 包中的init裡定義了三個方法 include,patterns,url。這些方法我們再熟悉不過。