想想看:什麽是壹個DI容器呢?它可以讓妳
連線連成應用程序...
...在
我們有“接線合”及“
腳本
動態
所以,壹個DI容器不過是壹個解釋的動態腳本語言。實際上,另壹種方式是:壹個典型的Java / .NET的DI容器不過是壹個蹩腳的解釋器壹個非常糟糕的動態腳本語言與對接醜陋,往往基於XML的語法。
當妳在Python程序,妳為什麽會想要壹個醜陋的,壞的腳本語言,當妳有壹個美麗的 CodeGo.net,輝煌的腳本語言在您的處置?其實,這是壹個更普遍的問題:當您在幾乎任何語言進行編程,為什麽妳想,當妳有Jython和IronPython的在您的處置壹個醜陋的,壞的腳本語言?
因此,要概括壹下:DI / IOC的做法是壹樣重要的在Python中,因為它是在Java中,對於完全相同的原因。該DI / IOC的但是,是建立在語言和經常如此輕巧的消失。 (這裏有壹個比喻:在組裝,子程序調用是壹個相當大的交易-妳要保存妳的局部變量和寄存器保存返回地址的指令指針更改為妳所呼叫的子程序,安排它跳回妳的子程序當它完成時,把那裏的被叫方可以找到他們,等IOW:在組裝,“子程序調用”是壹種設計模式,和之前有類似的Fortran語言,其中有建於子程序調用,人們建立自己的自己的“子程序妳會說,子程序調用是”在Python中,只是妳不'子程序
BTW:對於什麽樣子采取DI其邏輯的例子來看看吉rad的Bracha的新話編程語言以及他的著作的主題:
構造函數是有害的
註入死刑
禁止對導入(續)
2.
部分原因是模塊系統工作在Python的方式。妳可以得到壹種“單身”free的,只是從壹個模塊中導入它。定義壹個對象的實際實例中的壹個模塊,然後任何客戶端端代碼可以導入並真正得到壹個工作,全面構建/填充對象。
這是相對於Java的,在那裏妳不導入對象的實際情況。妳總是有自己實例化它們,(排序的IoC / DI樣式的方法)。您可以減輕不必自己所擁有的靜態(或實際工廠類)實例化壹切的trouble,但妳仍然招致實際創建新的每項資源開銷
3.
使得Django的控制反轉的。例如,數據庫服務器被選中的配置文件,然後提供相應的數據庫封裝實例的數據庫客戶端端。
不同的是,Python有壹流的類型。數據類型,包括類,都是自己的對象。如果妳想要壹個特定的類,只是這個類。例如:
if config_dbms_name == 'postgresql':
import psycopg
self.database_interface = psycopg
elif config_dbms_name == 'mysql':
...
再後來的代碼可以通過書面表單創建壹個數據庫接口:
my_db_connection = self.database_interface()
# Do stuff with database.
取而代之的樣板工廠的函數,Java和C ++的需要,Python做它與普通的代碼壹行或兩行。這是函數性命令式編程的力量。
4.
在我看來,這樣的事情依賴註入是壹個剛性的,當代碼過於沈重的主體輕易改變,妳會發現自己不得不挑了小部分,定義接口為他們,然後讓人們改變行為癥狀通過該插入這些接口的對象。這壹切都很好,但最好避免在首位那種。
這也是壹個靜態類型語言的癥狀。當妳要表達抽象的唯壹工具是繼承,那麽這就是幾乎什麽無處不在。話雖如此,C ++是非常類似的,但從來沒有拿起迷戀建設者和接口無處不在的Java開發人員做了。這是很容易得到過度旺盛能夠以靈活且可擴展的,很少真正的好處寫了太多的通用代碼的成本的夢想。我認為這是壹個文化的東西。
通常情況下,我認為Python的人來選擇合適的工具來完成工作,這是壹個連貫的和簡單的整體,而不是壹個真正的工具(壹個可能的插件),可以做什麽,但提供了可能的配置排列讓人眼花繚亂。還是有可互換的零件在必要時,但不需要定義固定接口,由於鴨打字和語言的相對簡單的靈活性大表單主義。
5.
避風港'的Python在好幾年,但我會說,它更多的是與它是壹個動態類型的語言比什麽都重要。舉個簡單的例子,在Java中,如果我想測試寫信給標準輸出適當地我DI和傳遞任何的PrintStream捕捉寫入的文字並進行驗證。當我在Ruby中我的工作,但是,我可以動態替換“看跌期權”的方法在標準輸出做驗證,留出來的圖片。如果我創建壹個抽象的唯壹原因是測試類,“它(認為文件系統操作或Java中的時鐘),那麽直接投資/ IoC創建的解決方案。
6.
我回來“約爾格?W米塔格”回答:“DI / IOC的Python是如此輕巧的消失”。
要備份此看壹看在Martin Fowler的例子移植從Java到Python:Python的:Design_Patterns:Inversion_of_Control
正如您可以從上面的鏈接,壹個“容器”在Python中看到可以寫成8行代碼:
class Container:
def __init__(self, system_data):
for component_name, component_class, component_args in system_data:
if type(component_class) == types.ClassType:
args = [self.__dict__[arg] for arg in component_args]
self.__dict__[component_name] = component_class(*args)
else:
self.__dict__[component_name] = component_class
7.
IoC和ruby,這是我的想法,為什麽它沒有被廣泛流傳
更新:
我不支持那個網站了,鏈接不工作,但可以在這裏閱讀
8.
其實,這是很容易寫出足夠幹凈的代碼與DI(我不知道,會不會被/ Python的停留,然後,但無論如何:)),例如我其實perefer這樣編碼:
def polite(name_str):
return "dear " + name_str
def rude(a):
return name_str + ", you, moron"
def greet(name_str, call=polite):
print "Hello, " + call(name_str) + "!"
_
>>greet("Peter")
Hello, dear Peter!
>>greet("Jack", rude)
Hello, Jack, you, moron!
是的,這可以看作是函數/類只是壹個簡單的表單,但它確實工作。所以,也許Python的默認附帶的電池足夠在這裏了。
P.S.我也貼這種幼稚的做法壹個更大的示例在動態評估在Python簡單的布爾邏輯。