動態語言、靜態語言及動態語言的“鴨子類型“


動態語言與靜態語言:

所謂動態和靜態,是指程序中類型。類型又是指class,int等定義,比如變量的類型,函數的入參類型,返回值類型。動態類型語言,表示在編寫程序的時候,無需制定類型,是運行時檢查;靜態類型語言,表示在編寫程序的時候,需要顯式地制定各種類型,在編譯的時候就會被檢查。

 

有人說靜態類型語言叫強類型語言,是指需要進行變量/對象類型聲明的語言,一般情況下需要編譯執行。

例如C/C++/Java/C#

有人說動態類型語言叫弱類型語言,是指不需要進行變量/對象類型聲明的語言,一般情況下不需要編譯(但也有編譯型的)。

例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等

 

Python是動態類型語言,官方的說法是Dynamic Typing

拿Python來舉例:動態語言中的變量無需申明,賦值時也不需要制定類型,任何時候都可以改變其指向的類型,函數的返回值也不固定,不同的入參得到的可以是不同類型的返回值。

 

 

動態語言的“鴨子類型”:

什么是動態語言的“鴨子類型”?

比如,我們寫了一個函數Test_Duck(),這個函數的入參是一個特定類型的對象(本例為Animal類型),這個函數就干一個事情,就是調用對象的run()函數。假設這個類型是Dog,Dog繼承Animal,現在我們有兩個對象,dog和animal,分比是類型Dog和Animal。

如果我們把a和b作為入參傳入Test_Duck(),Dog和Animal都有run()成員函數,執行都OK。

這時,如果我們再定義一個類型Test,Test跟Animal和Dog沒有任何關系,唯一的聯系都是,Test也有一個run()函數。假設test是Test的一個對象,我們把test傳入Test_Duck(),一樣可以得到執行。

本來我們設計Test_Duck()函數,是為了傳入Dog和Animal的對象,或者繼承Dog和Animal的其它新的類型對象,但是,突然出現了一個Test,跟Dog和Animal沒有任何關系,Test的對象也可以傳入Test_Duck()函數。我們說Test就是“鴨子類型”(A-like object)。

 

class Animal(object):
    def run(self):
        print('Animal is running')

class Dog(Animal):
    def run(self):
        print('Dog is running ')


class Test(Animal):
    def run(self):
        print('Test is right')

def Test_Duck(animal):
    animal.run()

dog = Dog()
dog.run()


test = Test()

Test_Duck(test)

 

運行結果為:

================== RESTART: E:/Python_pro/LXF/Class_Run.py ==================
Dog is running 
Test is right

 

這就是動態語言的“鴨子類型”,它並不要求嚴格的繼承體系,一個對象只要“看起來像鴨子,走起路來像鴨子”,那它就可以被看做是鴨子。

Python的“file-like object“就是一種鴨子類型。對真正的文件對象,它有一個read()方法,返回其內容。但是,許多對象,只要有read()方法,都被視為“file-like object“。許多函數接收的參數就是“file-like object“,你不一定要傳入真正的文件對象,完全可以傳入任何實現了read()方法的對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM