這篇文章給大家介紹Python中self的四個(gè)秘密分別是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
策勒網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,策勒網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為策勒近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的策勒做網(wǎng)站的公司定做!
毫無(wú)疑問(wèn),幾乎每一門(mén)Python課程都有一個(gè)關(guān)于(class)類(lèi)的講座——面向?qū)ο缶幊陶Z(yǔ)言的基本構(gòu)建模塊之一。
當(dāng)您通過(guò)一些示例學(xué)習(xí)它時(shí),您將注意到在Python類(lèi)中定義的許多函數(shù)都將self作為它們的第一個(gè)參數(shù)。例如,在下面的代碼片段中,我們聲明了一個(gè)名為Student的類(lèi),它的greet()方法的第一個(gè)參數(shù)是self。但是,函數(shù)根本沒(méi)有使用self,所以這里的self到底是從哪里來(lái)的呢?這對(duì)許多初學(xué)者來(lái)說(shuō)是第一個(gè)謎。
>>> class Student: ... def greet(self, name): ... print('Good Morning, ' + name) ... >>> student = Student() >>> student.greet('John') Good Morning, John
同樣奇怪的是,當(dāng)我們使用這個(gè)函數(shù)時(shí),我們并沒(méi)有給self參數(shù)設(shè)置任何東西,這是困擾我們的另一個(gè)謎題。在這篇文章中,我們將與學(xué)習(xí)者分享一些Python中self的奧秘。
在開(kāi)始處理這個(gè)謎題之前,我們需要理解兩個(gè)基本的相關(guān)概念:類(lèi)和實(shí)例。當(dāng)然,解決所有這些謎題需要額外的知識(shí),而不僅僅是類(lèi)和實(shí)例,我將在接下來(lái)的討論中澄清這一點(diǎn)。如果你對(duì)這兩個(gè)概念都很了解,你可以跳過(guò)下一段,這段只是對(duì)這兩個(gè)概念的簡(jiǎn)要概述。
創(chuàng)建Python類(lèi)就是聲明一種新的對(duì)象類(lèi)型,它提供了一種將數(shù)據(jù)和功能捆綁在一起的機(jī)制。在上面的示例中,我們創(chuàng)建了一個(gè)名為Student的類(lèi),并使用它創(chuàng)建了一個(gè)名為Student的學(xué)生類(lèi)型的對(duì)象。這個(gè)對(duì)象被稱(chēng)為student類(lèi)的實(shí)例。此外,類(lèi)還可以提供通常稱(chēng)為屬性的特定功能,例如示例中的greet()函數(shù)。我們使用三個(gè)內(nèi)省(introspection)函數(shù)(type()、isinstance()和hasattr())來(lái)檢查相關(guān)信息。
>>> type(Student) <class 'type'> >>> type(student) <class '__main__.Student'> >>> isinstance(student, Student) True >>> hasattr(Student, 'greet') True
我可以簡(jiǎn)單地告訴您,greet()函數(shù)中的self參數(shù)是上面示例中的student實(shí)例。更一般地說(shuō),是實(shí)例調(diào)用這個(gè)函數(shù)。以下是支持證據(jù):
>>> class Student: ... def greet(self, name): ... print(id(self)) ... print('Good Morning, ' + name) ... >>> student = Student() >>> student.greet('John') 4546580944 Good Morning, John >>> id(student) 4546580944
在上面的代碼中,我們修改了greet()函數(shù),要求它使用內(nèi)省id()函數(shù)向我們顯示self參數(shù)的內(nèi)存地址。如您所見(jiàn),self參數(shù)和實(shí)例student是同一個(gè)對(duì)象,因?yàn)樗鼈兙哂邢嗤膬?nèi)存地址。
繼續(xù)上一節(jié)中展示的示例,當(dāng)我們使用實(shí)例student調(diào)用greet()函數(shù)時(shí),這個(gè)函數(shù)通常被稱(chēng)為實(shí)例方法——一個(gè)對(duì)某個(gè)類(lèi)的實(shí)例可用的函數(shù)。但是,如果我們檢查這個(gè)屬性的類(lèi)型,就會(huì)顯示一些不同的東西。
>>> student = Student() >>> student.greet <bound method Student.greet of <__main__.Student object at 0x10eff5750>>
如上所述,實(shí)例student的greet屬性稱(chēng)為綁定方法。具體來(lái)說(shuō),它被綁定到Student類(lèi)的greet屬性。
為了準(zhǔn)確理解這意味著什么,讓我們看看下面的代碼:
>>> Student.greet(student, 'John') Good Morning, John
結(jié)合開(kāi)頭的示例,您可能會(huì)注意到這段代碼中的三件事:
這個(gè)函數(shù)的調(diào)用者是類(lèi)Student,而不是實(shí)例student。
在這個(gè)調(diào)用中設(shè)置了self和name參數(shù),這與student調(diào)用初始函數(shù)時(shí)忽略self參數(shù)不同。
兩個(gè)函數(shù)調(diào)用都產(chǎn)生了相同的輸出。它們本質(zhì)上用的是同一個(gè)函數(shù)。
通過(guò)實(shí)現(xiàn)這些信息,您可能已經(jīng)猜到在使用實(shí)例student調(diào)用greet()函數(shù)時(shí),幕后發(fā)生了什么。
如上圖所示,當(dāng)實(shí)例student調(diào)用greet(' John ')方法時(shí),解釋器將處理此函數(shù)調(diào)用,作為類(lèi)Student將調(diào)用者(即實(shí)例student)和name參數(shù)(即' John ')發(fā)送給greet(self, name)函數(shù),該函數(shù)打印“Good Morning, John”。
對(duì)于感興趣的讀者,這里有幾件事要知道,可以幫助你更深入地了解這個(gè)謎。當(dāng)創(chuàng)建一個(gè)Python類(lèi)時(shí),它聲明的函數(shù)就是這個(gè)類(lèi)的屬性(稱(chēng)為函數(shù)對(duì)象)。換句話說(shuō),類(lèi)“擁有”這些函數(shù)。類(lèi)的實(shí)例不會(huì)直接實(shí)現(xiàn)這些函數(shù)。相反,它們將具有與類(lèi)中實(shí)現(xiàn)的相應(yīng)函數(shù)綁定的相同屬性(即實(shí)例方法)。
似乎在所有這些已定義的函數(shù)中,我們都使用self作為它們的第一個(gè)參數(shù)。有些人可能錯(cuò)誤地認(rèn)為self是Python為這些用例保留的關(guān)鍵字。然而,事實(shí)并非如此。請(qǐng)看下面一個(gè)簡(jiǎn)單的例子:
>>> def=5 File "<stdin>", line 1 def=5 ^ SyntaxError: invalid syntax >>> class=4 File "<stdin>", line 1 class=4 ^ SyntaxError: invalid syntax >>> self=3
你可能知道,def和class是Python中的關(guān)鍵字,我們不能用它們作為變量名。然而,我們可以在定義函數(shù)的上下文之外使用self作為變量名,這表明它在Python中不是保留關(guān)鍵字。
在上面的例子中,我們重復(fù)引用了greet()函數(shù)。正如我們已經(jīng)討論過(guò)的,我們將這個(gè)函數(shù)實(shí)現(xiàn)為一個(gè)實(shí)例方法,這樣它就可以被這個(gè)Student類(lèi)的所有實(shí)例使用。在這種情況下,self是必需的。下面是一些證據(jù):
>>> class Teacher: ... def say_hello(name): ... print('Hello, ' + name) ... >>> teacher = Teacher() >>> teacher.say_hello('John') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: say_hello() takes 1 positional argument but 2 were given
這里有一些分析。如前所述,當(dāng)實(shí)例teacher調(diào)用say_hello()方法時(shí),發(fā)生的事情是執(zhí)行teacher .say_hello()函數(shù),并將實(shí)例對(duì)象teacher和' John '設(shè)置為函數(shù)調(diào)用。這就是為什么錯(cuò)誤說(shuō)“2是給定的。這與函數(shù)的定義相反,函數(shù)的定義只有一個(gè)參數(shù)(name)。
然而,還有兩件事與這個(gè)謎有關(guān),你可能想知道:
雖然聲明實(shí)例方法需要包含self參數(shù),但它不必命名為self。在這個(gè)場(chǎng)景中使用這個(gè)名稱(chēng)只是每個(gè)Python程序員都能欣賞的一種約定。下面是一個(gè)例子,它可以被命名為其他東西而不會(huì)引起任何問(wèn)題。盡管它在語(yǔ)法上是正確的,但不推薦使用,因?yàn)樗粫?huì)讓其他Python程序員感到困惑:
>>> class Teacher: ... def say_hello(professor, name): ... print('Hello, ' + name) ... >>> teacher = Teacher() >>> teacher.say_hello('John') Hello, John
在聲明其他函數(shù)(如類(lèi)和靜態(tài)方法)時(shí),不需要使用self參數(shù)。對(duì)類(lèi)和靜態(tài)方法的清晰解釋將是以后文章的主題。但我在這里可以展示的是,當(dāng)我們聲明一個(gè)類(lèi)方法時(shí),函數(shù)確實(shí)有一些類(lèi)似于在實(shí)例方法中使用self的東西,它通常被稱(chēng)為cls,引用類(lèi)對(duì)象本身。它與具體實(shí)例無(wú)關(guān)。下面是一個(gè)例子:
>>> class Student: ... def __init__(self, name): ... self.name = name ... @classmethod ... def with_names(cls, first_name, last_name): ... return cls(first_name + ' ' + last_name) ... >>> student = Student.with_names('John', 'Smith') >>> student.name 'John Smith'
關(guān)于Python中self的四個(gè)秘密分別是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
本文題目:Python中self的四個(gè)秘密分別是什么
本文來(lái)源:http://jinyejixie.com/article30/ggeopo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、動(dòng)態(tài)網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、企業(yè)網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)