成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解開Python中self的四個秘密

開發 前端
毫無疑問,幾乎每一門Python課程都有一個關于(class)類的講座——面向對象編程語言的基本構建模塊之一。

self的謎團

毫無疑問,幾乎每一門Python課程都有一個關于(class)類的講座——面向對象編程語言的基本構建模塊之一。

當您通過一些示例學習它時,您將注意到在Python類中定義的許多函數都將self作為它們的第一個參數。例如,在下面的代碼片段中,我們聲明了一個名為Student的類,它的greet()方法的第一個參數是self。但是,函數根本沒有使用self,所以這里的self到底是從哪里來的呢?這對許多初學者來說是第一個謎。

  1. >>> class Student: 
  2. ...     def greet(self, name): 
  3. ...         print('Good Morning, ' + name) 
  4. ...  
  5. >>> student = Student() 
  6. >>> student.greet('John'
  7. Good Morning, John 

同樣奇怪的是,當我們使用這個函數時,我們并沒有給self參數設置任何東西,這是困擾我們的另一個謎題。在這篇文章中,我們將與學習者分享一些Python中self的奧秘。

[[378103]]

1. 它代表什么?

在開始處理這個謎題之前,我們需要理解兩個基本的相關概念:類和實例。當然,解決所有這些謎題需要額外的知識,而不僅僅是類和實例,我將在接下來的討論中澄清這一點。如果你對這兩個概念都很了解,你可以跳過下一段,這段只是對這兩個概念的簡要概述。

創建Python類就是聲明一種新的對象類型,它提供了一種將數據和功能捆綁在一起的機制。在上面的示例中,我們創建了一個名為Student的類,并使用它創建了一個名為Student的學生類型的對象。這個對象被稱為student類的實例。此外,類還可以提供通常稱為屬性的特定功能,例如示例中的greet()函數。我們使用三個內省(introspection)函數(type()、isinstance()和hasattr())來檢查相關信息。

  1. >>> type(Student) 
  2. <class 'type'
  3. >>> type(student) 
  4. <class '__main__.Student'
  5. >>> isinstance(student, Student) 
  6. True 
  7. >>> hasattr(Student, 'greet'
  8. True 

我可以簡單地告訴您,greet()函數中的self參數是上面示例中的student實例。更一般地說,是實例調用這個函數。以下是支持證據:

  1. >>> class Student: 
  2. ...     def greet(self, name): 
  3. ...         print(id(self)) 
  4. ...         print('Good Morning, ' + name) 
  5. ...  
  6. >>> student = Student() 
  7. >>> student.greet('John'
  8. 4546580944 
  9. Good Morning, John 
  10. >>> id(student) 
  11. 4546580944 

在上面的代碼中,我們修改了greet()函數,要求它使用內省id()函數向我們顯示self參數的內存地址。如您所見,self參數和實例student是同一個對象,因為它們具有相同的內存地址。

解開Python中self的四個秘密

2. 為什么不需要在函數調用中設置它呢?

繼續上一節中展示的示例,當我們使用實例student調用greet()函數時,這個函數通常被稱為實例方法——一個對某個類的實例可用的函數。但是,如果我們檢查這個屬性的類型,就會顯示一些不同的東西。

  1. >>> student = Student() 
  2. >>> student.greet 
  3. <bound method Student.greet of <__main__.Student object at 0x10eff5750>> 

如上所述,實例student的greet屬性稱為綁定方法。具體來說,它被綁定到Student類的greet屬性。

為了準確理解這意味著什么,讓我們看看下面的代碼:

  1. >>> Student.greet(student, 'John'
  2. Good Morning, John 

結合開頭的示例,您可能會注意到這段代碼中的三件事:

  1. 這個函數的調用者是類Student,而不是實例student。
  2. 在這個調用中設置了self和name參數,這與student調用初始函數時忽略self參數不同。
  3. 兩個函數調用都產生了相同的輸出。它們本質上用的是同一個函數。

通過實現這些信息,您可能已經猜到在使用實例student調用greet()函數時,幕后發生了什么。

解開Python中self的四個秘密

如上圖所示,當實例student調用greet(' John ')方法時,解釋器將處理此函數調用,作為類Student將調用者(即實例student)和name參數(即' John ')發送給greet(self, name)函數,該函數打印“Good Morning, John”。

對于感興趣的讀者,這里有幾件事要知道,可以幫助你更深入地了解這個謎。當創建一個Python類時,它聲明的函數就是這個類的屬性(稱為函數對象)。換句話說,類“擁有”這些函數。類的實例不會直接實現這些函數。相反,它們將具有與類中實現的相應函數綁定的相同屬性(即實例方法)。

3.self是一個關鍵詞嗎?

似乎在所有這些已定義的函數中,我們都使用self作為它們的第一個參數。有些人可能錯誤地認為self是Python為這些用例保留的關鍵字。然而,事實并非如此。請看下面一個簡單的例子:

  1. >>> def=5 
  2.   File "<stdin>", line 1 
  3.     def=5 
  4.        ^ 
  5. SyntaxError: invalid syntax 
  6. >>> class=4 
  7.   File "<stdin>", line 1 
  8.     class=4 
  9.         ^ 
  10. SyntaxError: invalid syntax 
  11. >>> self=3 

你可能知道,def和class是Python中的關鍵字,我們不能用它們作為變量名。然而,我們可以在定義函數的上下文之外使用self作為變量名,這表明它在Python中不是保留關鍵字。

解開Python中self的四個秘密

4. 我們必須在這些函數聲明中使用self嗎?

在上面的例子中,我們重復引用了greet()函數。正如我們已經討論過的,我們將這個函數實現為一個實例方法,這樣它就可以被這個Student類的所有實例使用。在這種情況下,self是必需的。下面是一些證據:

  1. >>> class Teacher: 
  2. ...     def say_hello(name): 
  3. ...         print('Hello, ' + name) 
  4. ... 
  5. >>> teacher = Teacher() 
  6. >>> teacher.say_hello('John'
  7. Traceback (most recent call last): 
  8.   File "<stdin>", line 1, in <module> 
  9. TypeError: say_hello() takes 1 positional argument but 2 were given 

這里有一些分析。如前所述,當實例teacher調用say_hello()方法時,發生的事情是執行teacher .say_hello()函數,并將實例對象teacher和' John '設置為函數調用。這就是為什么錯誤說“2是給定的。這與函數的定義相反,函數的定義只有一個參數(name)。

然而,還有兩件事與這個謎有關,你可能想知道:

  • 雖然聲明實例方法需要包含self參數,但它不必命名為self。在這個場景中使用這個名稱只是每個Python程序員都能欣賞的一種約定。下面是一個例子,它可以被命名為其他東西而不會引起任何問題。盡管它在語法上是正確的,但不推薦使用,因為它只會讓其他Python程序員感到困惑:
  1. >>> class Teacher: 
  2. ...     def say_hello(professor, name): 
  3. ...         print('Hello, ' + name) 
  4. ... 
  5. >>> teacher = Teacher() 
  6. >>> teacher.say_hello('John'
  7. Hello, John 
  • 在聲明其他函數(如類和靜態方法)時,不需要使用self參數。對類和靜態方法的清晰解釋將是以后文章的主題。但我在這里可以展示的是,當我們聲明一個類方法時,函數確實有一些類似于在實例方法中使用self的東西,它通常被稱為cls,引用類對象本身。它與具體實例無關。下面是一個例子:
  1. >>> class Student: 
  2. ...     def __init__(self, name): 
  3. ...         self.name = name 
  4. ...     @classmethod 
  5. ...     def with_names(cls, first_name, last_name): 
  6. ...         return cls(first_name + ' ' + last_name) 
  7. ...  
  8. >>> student = Student.with_names('John''Smith'
  9. >>> student.name 
  10. 'John Smith' 

英文原文:

Unlock the 4 Mysteries of self in Python | by Yong Cui | Better Programming | Medium

 

 

 

責任編輯:張燕妮 來源: 今日頭條
相關推薦

2013-04-11 12:56:14

費道明HTML

2022-05-04 12:44:57

Python編程語言

2013-10-22 09:30:22

2022-01-12 15:50:24

JavaScript開發循環

2024-11-14 09:00:00

Python編程元編程

2021-08-14 09:48:02

ReentrantLock多線編程

2020-08-13 10:29:55

項目管理項目經理CIO

2011-07-14 15:23:34

java

2013-03-18 13:31:28

2024-06-25 12:45:05

2024-09-26 10:00:00

Python文件處理

2024-05-10 12:33:06

flask裝飾器

2022-02-23 15:09:18

數字化轉型國有企業數據

2023-10-26 07:47:35

JavaScript代碼變量

2010-03-30 11:00:46

Oracle 數據

2023-08-21 13:39:57

開發桌面Ubuntu

2020-06-04 08:15:53

Kubernetes容器PaaS

2022-06-27 23:31:01

JavaScript框架開發

2025-04-21 06:25:00

2011-05-18 09:32:14

java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲美女天堂网 | 亚洲精品久久久久久久久久久 | 亚洲小视频在线观看 | 日韩精品一区二区三区在线播放 | 欧美日韩国产在线观看 | 亚洲欧美在线一区 | 亚洲人成在线观看 | 国产一区二区免费 | 色婷婷精品久久二区二区蜜臂av | 免费激情 | 99re国产精品 | 国产成人高清视频 | 91精品91久久久 | 91视频精选| 久久69精品久久久久久久电影好 | 亚洲精品一区二区二区 | 亚洲一区二区三区福利 | 日韩精品视频在线免费观看 | 亚洲日本成人 | hsck成人网| 亚洲精品视频在线播放 | 国产精品久久久久久久久久久久 | 日本一区二区三区免费观看 | 天天操夜夜爽 | 盗摄精品av一区二区三区 | 中文字幕一区在线观看视频 | 黄色av免费网站 | 精品三区 | 日本精品一区二区三区在线观看视频 | 91中文字幕在线 | 婷婷五月色综合香五月 | 欧美日韩在线高清 | 久久99这里只有精品 | 黄色a视频 | 亚洲九九| 欧美一级毛片久久99精品蜜桃 | 国产自产c区 | 国产精品一区一区三区 | aaa级片| 成人视屏在线观看 | 久久伊人亚洲 |