Python類中的__init__() 和 self 的解析


1、Python中self的含義

self,英文單詞意思很明顯,表示自己,本身。

此處有幾種潛在含義:

1.這里的自己,指的是,實例Instance本身。

2.同時, 由於說到“自己”這個詞,都是和相對而言的“其他”而說的;而此處的其他,指的是,類Class,和其他變量,比如局部變量,全局變量等。

此處的self,是個對象(Object),是當前類的實例。

因此,對應的self.valueName 和 self.function()中的valueName:表示self對象,即實例的變量。與其他的,Class的變量,全局的變量,局部的變量,是相對應的。

function:表示是調用的是self對象,即實例的函數。與其他的全局的函數,是相對應的。

2、Python中為何要有self

那就是:

在類的代碼(函數)中,需要訪問當前的實例中的變量和函數的,即,訪問Instance中的:

  • 對應的變量(屬性,property):Instance.ProperyNam,去讀取之前的值和寫入新的值

  • 調用對應函數(function):Instance.function(),即執行對應的動作

-> 而需要訪問實例的變量和調用實例的函數,當然需要對應的實例Instance對象本身

-> 而Python中就規定好了,函數的第一個參數,就必須是實例對象本身,並且建議,約定俗成,把其名字寫為self

-> 所以,我們需要self(需要用到self)

而如果沒有用到self,即代碼中,去掉self后,那種寫法所使用到的變量,實際上不是你所希望的,不是真正的實例中的變量和函數,而是的訪問到了其他部分的變量和函數了。甚至會由於沒有合適的初始化實例變量,而導致后續無法訪問的錯誤。

下面,就通過代碼,來演示,如果去掉self,或者沒有合理的使用self,會出現哪些錯誤。

3、首先來看一下__init__()和self對象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: antcolonies
 
class  Person( object ):
     def  __init__( self , name, lang, website):
         self .name  =  name
         self .lang  =  lang
         self .website  =  website
 
         print ( 'self: ' self )
         print ( 'type of self: ' type ( self ))
'''
未實例化時,運行程序,構造方法沒有運行
'''
 
=  Person( 'Tim' 'English' 'www.universal.com' )   
 
'''實例化后運行的結果
self:  <__main__.Person object at 0x00000000021EAF98>
type of self:  <class '__main__.Person'>
'''

可以看出self為實例變量p,是一個Person類型的對象。

1
2
3
4
5
6
7
8
9
10
11
class  Dog( object ):       
     def  __init__( self ,name,dog_type):
         self .name  =  name
         self . type  =  dog_type
   
     def  sayhi( self ):
         print ( "hello,I am a dog, my name is " , self .name)
   
   
=  Dog( 'LiChuang' , "京巴" )             # 實例化
d.sayhi()

以下是d = Dog('LiChuang',"京巴")實例化的示意圖:

4、如果沒有在__init__中初始化對應的實例變量的話,導致后續引用實例變量會出錯

如下代碼,完整的演示了,如果沒有在類Class的最初的__init__函數中,正確的初始化實例變量,則會導致后續沒有變量可用,因而出現AttributeError的錯誤:

從上述代碼可見,由於在類的初始化(實例化)的__init__函數中,沒有給self.name設置值,使得實例中,根本沒有name這個變量,導致后續再去訪問self.name,就會出現AttributeError的錯誤了。

對應的,如果寫成self.name,則意思就正確了,就是初始化的時候,給實例中新增加,並且正常設置了正確的值newPersionName了,所以后續再去通過self.name,就可以訪問到,當前實例中正確的變量name了。

相應的正確寫法的代碼如下:

5、在函數中,使用對應的變量,雖然代碼是可以運行的,但是實際上卻是使用的,不是實例中的變量

有時候,雖然你寫的代碼,可以運行,但是使用到的變量,由於沒有加self,實際上是用到的不是實例的變量,而是其他的變量。

此類問題,主要和Python中的變量的作用域有關,但是此處例子中,也和是否使用self有關:

其中,可見,此處開始__init__中,沒有給self實例初始化對應的name,

而后面的函數sayYourName中,雖然可以調用到self.name而沒有出現AttributeError錯誤,

但是實際上此處的值,不是所期望的,傳入的name,即"Tim",而是類中的name的值,即"class global name"。

 

以上參考了: http://www.crifan.com/summary_the_meaning_of_self_and___init___in_python_and_why_need_them/

                  http://www.jb51.net/article/56082.htm


免責聲明!

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



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