亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        Python的對(duì)象與型式

        2017-09-28 19:02:08喬林
        計(jì)算機(jī)教育 2017年9期
        關(guān)鍵詞:型式對(duì)象

        喬林

        摘 要:作為動(dòng)態(tài)語言,Python與其他靜態(tài)編譯語言有很大差別,其對(duì)象與型式的概念及關(guān)系非常讓人迷惑。文章討論P(yáng)ython程序設(shè)計(jì)語言中對(duì)象、型式與量的基本概念和關(guān)系,闡釋這些概念的內(nèi)涵與外延,指出初學(xué)者容易混淆之處,并給出教學(xué)過程中的一點(diǎn)心得體會(huì)。

        關(guān)鍵詞:Python;對(duì)象;型式;量

        0 引 言

        對(duì)于Python程序設(shè)計(jì)語言對(duì)象與型式的概念、關(guān)系等基本概念,如果沒有清晰的認(rèn)知,那么所編寫的Python程序(腳本)重者無法運(yùn)行或者得到錯(cuò)誤的結(jié)果,輕者可能隱含難以察覺和調(diào)試的邏輯錯(cuò)誤。因此,了解Python程序設(shè)計(jì)語言中對(duì)象、型式與量的基本概念和關(guān)系,掌握文字與量、名空間與作用域、全局量與局部量的概念以及這些基礎(chǔ)概念對(duì)量(對(duì)象)可能造成的影響至關(guān)重要。

        1 對(duì)象與型式

        1.1 對(duì) 象

        對(duì)象(object)是一種數(shù)據(jù)抽象或數(shù)據(jù)結(jié)構(gòu)抽象,用來表示程序中需要處理或已處理的信息。在Python程序設(shè)計(jì)語言中,對(duì)象具有3個(gè)基本特征:本征值(identity)、型式(type)和值(value)。

        本征值是用于區(qū)分不同對(duì)象的信息,因而特征之一是應(yīng)具有唯一性。在Python程序設(shè)計(jì)語言中,本征值的表示方式與Python程序設(shè)計(jì)語言的具體實(shí)現(xiàn)有關(guān),一種典型的實(shí)現(xiàn)策略是使用對(duì)象在內(nèi)存中的存儲(chǔ)地址,如CPython的實(shí)現(xiàn)。本征值的另外一個(gè)特征是有常性(immutability),即一經(jīng)創(chuàng)設(shè)就不可改變。

        在Python程序設(shè)計(jì)語言中,可以使用本征值函數(shù)id()返回某個(gè)特定對(duì)象的本征值,如在Cpython實(shí)現(xiàn)中,id(1)與id(obj)分別返回對(duì)象1與對(duì)象obj的本征值。相應(yīng)地,也可以使用型式函數(shù)type()獲取某個(gè)對(duì)象的型式。

        在Python程序設(shè)計(jì)語言中,依據(jù)該對(duì)象是否可被改變,而分為有常對(duì)象(immutable)和無常對(duì)象(mutable)。

        一般而言,Python程序設(shè)計(jì)語言中的對(duì)象無常性由其型式確定。典型的示例,如數(shù)值(numeric)、字符串(string)和元組(tuple)為有常對(duì)象,詞典(dictionary)和列表(list)為無常對(duì)象;此外,有常容器(container)對(duì)象可能包含無常元素對(duì)象,前者值不可變,后者則不然。對(duì)于這兩點(diǎn),初學(xué)者必須時(shí)刻保持警覺,教師在教學(xué)過程中也必須闡釋清楚。

        1.2 型 式

        型式(type),簡(jiǎn)稱型,也稱類型。在純面向?qū)ο笳Z言出現(xiàn)之前,type用來表示相同性質(zhì)的數(shù)據(jù)集合。該集合雖然具有明確的操作集,厘定了可在該集合上實(shí)施的操作,但是并未在語言層面上對(duì)其進(jìn)行明晰的操作集定義,即數(shù)據(jù)及其操作是分離的。

        型,其最主要的目的是構(gòu)造該型式的對(duì)象。這意味著任何對(duì)象都必須有確切的型式,且一般不可改變。

        在面向?qū)ο蠹夹g(shù)出現(xiàn)之后,程序設(shè)計(jì)語言一般使用專用關(guān)鍵字來表示特定的將數(shù)據(jù)與操作辯證統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)——類,如C++程序設(shè)計(jì)語言中的關(guān)鍵字class(含擴(kuò)充定義的struct)。在類中,對(duì)象屬性(attribute)和行為(behavior)被統(tǒng)一描述和管理:對(duì)象屬性是類的數(shù)據(jù)成員;對(duì)象行為是該類或該類的某個(gè)對(duì)象上可執(zhí)行的操作成員,也稱為方法(method)。

        語言學(xué)上,class的翻譯為“類”,作為型(type)的一種,也可以稱為“類型”。這使得其與早期術(shù)語type之間,容易出現(xiàn)一定混淆——早期非class類型的type也被翻譯成“類型”。為避免引起誤解,將type更正為“型式”更佳,有助于區(qū)分class與type ——兩者在程序設(shè)計(jì)語言層面上并非同一概念。

        Python程序設(shè)計(jì)語言作為一種純粹的面向?qū)ο笳Z言,凡物皆為對(duì)象,這導(dǎo)致學(xué)生在學(xué)習(xí)時(shí)會(huì)面臨以下兩方面的困難。

        (1)class與type的本質(zhì)完全相同,類即為型,而型亦為類。此時(shí),討論其他編程語言中這兩者的差異,就沒有任何意義。因此,很多學(xué)習(xí)過其他面向?qū)ο笳Z言的學(xué)生在學(xué)習(xí)Python程序設(shè)計(jì)語言時(shí),反而會(huì)面臨概念理解上的困難。這一點(diǎn),授課教師必須在教學(xué)過程中表述清楚,以減少學(xué)生的困惑。

        (2)型也是可以在程序中操作的對(duì)象??梢哉J(rèn)為,型就是構(gòu)造對(duì)象的模板,然而在實(shí)際語言實(shí)現(xiàn)中,存在這樣一種情況,即一個(gè)對(duì)象本身實(shí)際上可以作為該型另外一個(gè)對(duì)象的模板。這意味著,型本身也可以作為對(duì)象來存儲(chǔ)和管理,并在程序運(yùn)行過程中作為模板,用于構(gòu)造該型的對(duì)象。因此,我們可以將程序編譯從靜態(tài)引向動(dòng)態(tài)。

        示例代碼一:

        >>> id(int)

        1707211232

        >>> type(int)

        >>> id(float)

        1707205632

        >>> type(float)

        >>> int is float

        False

        # 試試將一個(gè)浮點(diǎn)型賦值給一個(gè)整型

        >>> int = float

        >>> id(int)

        1707205632

        >>> type(int)

        >>> id(float)

        1707205632

        >>> type(float)

        >>> int is float

        True

        >>>

        1.3 型之相

        在Python程序設(shè)計(jì)語言中,類具有明確的型。類的定義語句負(fù)責(zé)創(chuàng)建(構(gòu)造)一個(gè)類型,而類型用于創(chuàng)建(構(gòu)造)該類型的對(duì)象(object)。

        構(gòu)造類的一個(gè)實(shí)際對(duì)象的過程稱為具象化(instantiation),也稱為實(shí)例化。實(shí)例化的結(jié)果為具象(instance object),也稱實(shí)例對(duì)象。

        實(shí)際上,在Python程序設(shè)計(jì)語言中,類定義結(jié)束時(shí),系統(tǒng)將構(gòu)造(創(chuàng)建)出該類的一個(gè)型象。如前所述,型亦為對(duì)象,因此,按照此型定義出的對(duì)象稱為對(duì)象(class object),也稱類象或類對(duì)象。

        對(duì)于初學(xué)者而言,這種概念上的差別非常容易讓人迷惑。類(型)本身就是構(gòu)造對(duì)象的模板,那么類對(duì)象或型對(duì)象是什么?在教學(xué)過程中,教師必須特別強(qiáng)調(diào)Python程序設(shè)計(jì)語言的類(型)動(dòng)態(tài)性,這一點(diǎn)與C語言和C++語言有很大的區(qū)別。因而,我們更傾向于將由類定義而創(chuàng)建(構(gòu)造)出來的類對(duì)象稱為型相,即使用“相”字區(qū)分實(shí)際對(duì)象的“象”字。

        也就是說,對(duì)于任意一個(gè)類,其類定義創(chuàng)建(構(gòu)造)了該類的一個(gè)型相;而通過該型相,程序員可以創(chuàng)建(構(gòu)造)該類的具象——具體的象。對(duì)于前者,構(gòu)造型相的過程,我們稱為體化(型體化);對(duì)于后者,構(gòu)造具象的過程被稱為具象化(象化)。體化的書面意義是指“以自己的行動(dòng)感化別人”,而“體”本身指“事物的本身或全部”“物質(zhì)存在的狀態(tài)或形狀”或“事物的格局、規(guī)矩”,因此用“體化”描述這個(gè)過程似乎更恰當(dāng)。

        2 量與對(duì)象

        2.1 文字與量

        文字(literal)是內(nèi)置類型的有常值,類似于數(shù)學(xué)或物理中的常數(shù),如0、3.1 416、2.718 28j、“Python”等。一方面,在Python程序設(shè)計(jì)語言中,文字亦對(duì)象;另一方面,量(variable)是引用特定對(duì)象的標(biāo)識(shí)符,類似數(shù)學(xué)中的代數(shù)。

        在Python程序設(shè)計(jì)語言中,量的處理相當(dāng)特殊。事實(shí)上,它已經(jīng)與C語言、C++語言等早期語言中的概念有了明顯差別。

        首先,量可以隨意引用數(shù)值、字符串或其他類型的對(duì)象;其次,量是標(biāo)識(shí)符(identifier),是名稱(name),但并不是該對(duì)象本身,僅僅是對(duì)“象”的引用(reference),即對(duì)該“對(duì)象”的“象”的引用;最后,對(duì)于Python程序設(shè)計(jì)語言中的量而言,賦值(assignment)即定義(definition),因而并不需要在使用量前作預(yù)先定義。這意味著賦值的目的并不是將賦值操作符右邊表達(dá)式的結(jié)果,存入該量所對(duì)應(yīng)的存儲(chǔ)空間,而是將代表該量的名稱(name)與賦值操作符右邊表達(dá)式的結(jié)果所對(duì)應(yīng)的值,束定(bind)或重新束定(rebind)在一起,以修改無常對(duì)象的屬性或值。

        這樣就引申出一個(gè)問題,即量的同一性(identity)問題——我們?nèi)绾闻袛鄡蓚€(gè)量是否引用了同一個(gè)對(duì)象。雖然Python程序設(shè)計(jì)語言提供兩個(gè)關(guān)鍵字(操作符)is和is not,用于測(cè)試量的同一性,但是實(shí)際問題是量的同一性依賴于Python程序設(shè)計(jì)語言的具體實(shí)現(xiàn),如我們可以認(rèn)定a = [] 與b = [] 總是引用不同的有常對(duì)象(空列表),a = b = [] 總是引用同一有常對(duì)象,卻并不能保證a = 1與b = 1是否引用了值為1的同一有常對(duì)象。

        2.2 名空間與作用域

        在概念上,名空間(namespace)是從名稱到對(duì)象的映射。在實(shí)現(xiàn)上,大多數(shù)名空間表現(xiàn)為符號(hào)表,以字典的形式來組織,而變量存儲(chǔ)其中。在Python腳本中存在多個(gè)相互獨(dú)立的名空間。

        一般而言,名空間具有如下特性:

        (1)標(biāo)識(shí)符獨(dú)立性:不同名空間的同名標(biāo)識(shí)符沒有任何關(guān)聯(lián);

        (2)標(biāo)識(shí)符唯一性:同一名空間中的標(biāo)識(shí)符不得重名;

        (3)名空間嵌套:一個(gè)名空間可以包含另外一個(gè)名空間。

        在Python程序設(shè)計(jì)語言中,名空間分為內(nèi)置名空間(built-in namespace)、全局名空間和局部名空間這3類。其中,內(nèi)置名空間為內(nèi)置名稱集合,如內(nèi)置函數(shù)名、內(nèi)置異常名等;全局名空間為模塊內(nèi)部的全局名稱集合;而局部名空間為函數(shù)調(diào)用時(shí)的本地名稱集合、對(duì)象的屬性集合、嵌套函數(shù)的本地名稱集合或類成員函數(shù)的本地名稱集合等。

        需要說明的是,全局名空間也稱模塊全局名空間,在讀入模塊定義時(shí)創(chuàng)建,且正常情況下在Python解釋器退出時(shí)刪除。此處所說的“全局”僅指在該模塊內(nèi)部為全局的。每個(gè)模塊都有獨(dú)立的全局名空間,導(dǎo)入模塊后方可訪問其中的全局標(biāo)識(shí)符;同時(shí),模塊中可能存在非全局標(biāo)識(shí)符,即使導(dǎo)入模塊也不可訪問,這一點(diǎn)是初學(xué)者很容易犯糊涂的地方,教師在教學(xué)時(shí)須予以重視。

        另一個(gè)相關(guān)的概念是作用域(scope)。定義上,作用域是指可訪問名空間中標(biāo)識(shí)符的文法區(qū)域,即在Python程序文本的某處,是否可以使用該名空間中的標(biāo)識(shí)符。

        雖然作用域與名空間在概念上有強(qiáng)關(guān)聯(lián),但是二者并不相同。一般認(rèn)為,不在某名空間中,就不能訪問該名空間中的標(biāo)識(shí)符;同時(shí),在某名空間中,也不一定能訪問該名空間中的標(biāo)識(shí)符。

        在Python程序設(shè)計(jì)語言中,作用域分為局部作用域、外層函數(shù)閉包作用域、全局作用域和內(nèi)置作用域這4類。其中,局部作用域位于最內(nèi)層,為函數(shù)(類成員函數(shù))、類或Lambda表達(dá)式形成的文法區(qū)域;外層函數(shù)閉包作用域?yàn)榍短缀瘮?shù)的外層函數(shù)形成的文法區(qū)域;全局作用域?yàn)槟K形成的文法區(qū)域;內(nèi)置作用域位于最外層,為包含內(nèi)置名稱的文法區(qū)域。

        在進(jìn)行標(biāo)識(shí)符查找時(shí),按照由內(nèi)向外的順序查找上述4種作用域。

        2.3 全局量與局部量

        一般將定義于類、函數(shù)、類成員函數(shù)或Lambda表達(dá)式之外場(chǎng)合的量稱為全局量;將定義于函數(shù)、類成員函數(shù)或Lambda表達(dá)式中的量稱為局部量。函數(shù)的形式參數(shù)與局部量類似,但是出于參數(shù)傳遞的原因,其與普通局部量有細(xì)微差異。

        需要說明的是,全局量與局部量位于不同的名空間,因而可重名;同時(shí),全局量和局部量重名時(shí),局部量可能遮蓋全局量的作用域,使其不可見。endprint

        在賦值即定義的原則下,Python程序設(shè)計(jì)語言中,全局量和局部量的差別經(jīng)常讓初學(xué)者迷惑,如以下3段代碼。

        示例代碼二:

        # n為全局量,位于全局名空間,其后代碼(包括函數(shù)內(nèi)部)均可訪問

        n = 42

        # 形式參數(shù)x也為局部量,位于局部名空間,函數(shù)內(nèi)部可訪問

        def double(x):

        # 訪問全局量n

        print( "Before being doubled in double(): n = ", n )

        # m為局部量,位于局部名空間,函數(shù)內(nèi)部可訪問

        m = x * 2

        print( "After being doubled in double(): m = ", m )

        print( "After being doubled in double(): n = ", n )

        return m

        print( "Before calling double() in __main__: n = ", n )

        # m為全局量,位于全局名空間,與函數(shù)內(nèi)部m為獨(dú)立的兩個(gè)對(duì)象

        m = double(n)

        print( "After calling double() in __main__: m = ", m )

        print( "After calling double() in __main__: n = ", n )

        示例代碼二的輸出結(jié)果如下:

        # 調(diào)用函數(shù)前,全局量n值為42

        Before calling double() in __main__: n = 42

        # 調(diào)用函數(shù)中,全局量n值為42(加倍前)

        Before being doubled in double(): n = 42

        # 調(diào)用函數(shù)中,局部量m值為84(加倍后)

        After being doubled in double(): m = 84

        # 調(diào)用函數(shù)中,全局量n值為42(加倍后)

        After being doubled in double(): n = 42

        # 調(diào)用函數(shù)后,全局量m接受加倍值84

        After calling double() in __main__: m = 84

        # 調(diào)用函數(shù)后,全局量n值維持42不變

        After calling double() in __main__: n = 42

        在示例代碼二中,n為全局量;m既可能為全局量,又可能為局部量,這與其所在的文法區(qū)域有關(guān),如函數(shù)內(nèi)部的m為局部量,函數(shù)定義之后使用的m為全局量。

        示例代碼三如下:

        # n為全局量,位于全局名空間,其后代碼(包括函數(shù)內(nèi)部)均可訪問

        n = 42

        def double(x):

        # 注釋下一條語句,否則無法束定局部量n,引發(fā)UnboundLocalError異常

        # print( "Before being doubled in double(): n = ", n )

        # 定義同名局部量n(賦值即定義),新對(duì)象具有局部作用域,整個(gè)函數(shù)內(nèi)部均有效

        # 局部量n遮蓋同名全局量n的部分作用域,使其不可見

        # 局部量n定義前雖不能訪問,但仍不允許上條注釋語句訪問全局量n

        # 換言之,即使前述被注釋的那條語句出現(xiàn)在局部量n定義之前,n也被解釋為局部量

        n = x * 2

        print( "After being doubled in double(): n = ", n )

        return n

        print( "Before calling double() in __main__: n = ", n )

        m = double(n)

        print( "After calling double() in __main__: m = ", m )

        print( "After calling double() in __main__: n = ", n )

        示例代碼三的輸出結(jié)果如下:

        # 調(diào)用函數(shù)前,全局量n值為42

        Before calling double() in __main__: n = 42

        # 調(diào)用函數(shù)中,局部量n值為 42

        After being doubled in double(): n = 84

        # 調(diào)用函數(shù)中,全局量m接受加倍值84

        After calling double() in __main__: m = 84

        # 調(diào)用函數(shù)后,全局量n維持原值42不變

        # 即全局量n與局部量n雖同名,但不是同一對(duì)象

        After calling double() in __main__: n = 42

        在示例代碼三中,視定義n時(shí)的文法區(qū)域,n可能為全局量,也可能為局部量;m則為全局量。相關(guān)代碼解釋已列入程序注釋,此處不再贅述。

        再看示例代碼四:

        # n為全局量,位于全局名空間,其后代碼(包括函數(shù)內(nèi)部)均可訪問

        n = 42

        # 直接使用全局量n,無需傳遞參數(shù)endprint

        def double():

        # 聲明全局量n,函數(shù)內(nèi)部對(duì)其賦值不會(huì)構(gòu)造新的局部對(duì)象

        global n

        print( "Before being doubled in double(): n = ", n )

        # 直接寫入全局量,而不是構(gòu)造新的局部對(duì)象

        n = n * 2

        print( "After being doubled in double(): n = ", n )

        return n

        print( "Before calling double() in __main__: n = ", n )

        m = double()

        print( "After calling double() in __main__: m = ", m )

        print( "After calling double() in __main__: n = ", n )

        示例代碼四的輸出結(jié)果如下:

        # 調(diào)用函數(shù)前,全局量n值為42

        Before calling double() in __main__: n = 42

        # 調(diào)用函數(shù)中,全局量n值為 42(加倍前)

        Before being doubled in double(): n = 42

        # 調(diào)用函數(shù)中,全局量n值更新為84(加倍后)

        After being doubled in double(): n = 84

        # 調(diào)用函數(shù)后,全局量m接受加倍值84

        After calling double() in __main__: m = 84

        # 調(diào)用函數(shù)后,全局量n維持更新后的值84不變

        After calling double() in __main__: n = 84

        由于賦值定義的特性,要在Python函數(shù)內(nèi)部修改全局量的值,就必須使用global將其聲明為全局量,原因是在函數(shù)內(nèi)部可以自由引用全局量,但不能對(duì)其賦值——賦值隱含著構(gòu)造新的同名局部對(duì)象。

        類似的關(guān)鍵字還有nonlocal,用于將其后標(biāo)識(shí)符解釋為非局部非全局的。查找標(biāo)識(shí)符時(shí),Python解釋器將從最內(nèi)層嵌套名空間向外查找,一直到全局名空間(不含);若未找到該標(biāo)識(shí)符,系統(tǒng)將引發(fā)SyntaxError異常。

        無論是global還是nonlocal,標(biāo)識(shí)符在其定義所在的代碼塊各處均有效,包括該聲明之前。

        3 結(jié) 語

        本文探討了Python程序設(shè)計(jì)語言中的對(duì)象、型式與量的基本概念和關(guān)系以及對(duì)象與型式的基本概念,指出了型相與具象的本質(zhì)及兩者之間的差異,并解釋了文字與量、名空間與作用域、全局量與局部量的概念,指出了這些基礎(chǔ)概念對(duì)量(對(duì)象)可能造成的影響。在實(shí)際編程時(shí),對(duì)這些概念的理解偏差極大地影響程序的健壯性和正確性,因而需要在教學(xué)過程中予以詳盡的說明。endprint

        猜你喜歡
        型式對(duì)象
        神秘來電
        睿士(2023年2期)2023-03-02 02:01:09
        幕墻型式對(duì)高層建筑室內(nèi)自然通風(fēng)影響的模擬
        煤氣與熱力(2021年9期)2021-11-06 05:22:48
        現(xiàn)代中小河流常用有壩壅水建筑物型式探討
        攻略對(duì)象的心思好難猜
        意林(2018年3期)2018-03-02 15:17:24
        軍持的型式分析與年代分期
        東方考古(2017年0期)2017-07-11 01:37:54
        基于熵的快速掃描法的FNEA初始對(duì)象的生成方法
        區(qū)間對(duì)象族的可鎮(zhèn)定性分析
        6-APA裂解過程攪拌型式的研究及改進(jìn)
        免费无码中文字幕a级毛片| 国产内射视频免费观看| 白白色发布视频在线播放| 很黄很色的女同视频一区二区| 亚洲αv在线精品糸列| 小荡货奶真大水真多紧视频| 人体内射精一区二区三区| 日本岛国大片不卡人妻| 日本免费播放一区二区| 友田真希中文字幕亚洲| 久久9精品区-无套内射无码| 国产偷国产偷亚洲清高| 成人国产乱对白在线观看| 国产少妇高潮在线视频| 免费av片在线观看网址| 区二区三区玖玖玖| 日日摸夜夜添夜夜添一区二区| 蜜臀av一区二区三区人妻在线| 在线亚洲日本一区二区| 中国孕妇变态孕交xxxx| 怡红院a∨人人爰人人爽| 手机看片福利日韩国产| 亚洲一区二区三区高清视频| 美腿丝袜在线一区二区| 亚洲精品久久久久中文字幕| 人人妻人人添人人爽日韩欧美| 午夜一区二区三区av| 国产一区二区三区青青草| 亚洲综合成人婷婷五月网址| 国产性一交一乱一伦一色一情| 亚洲欧美成人在线免费| 日韩av中文字幕波多野九色| 亚洲熟妇无码久久精品| 伊伊人成亚洲综合人网香| 国产精品一卡二卡三卡| 国产另类av一区二区三区| 欧美奶涨边摸边做爰视频| 毛片24种姿势无遮无拦| 动漫av纯肉无码av在线播放| 国产毛片精品av一区二区| 粉嫩av国产一区二区三区|