歡迎光臨
每天分享高質量文章

全面深入理解 Python 類與物件

(點選上方公眾號,可快速關註一起學Python)

作者:浪子燕青       連結:

http://www.langzi.fun/深入類與物件-中.html

 

類屬性和實體屬性查詢順序

屬性:在內部定義的方法或者變數

使用程式碼:

class magic:
    a = 'langzi'
    def __init__(self,x):
        self.x = x
        # 這裡傳入的x已經屬於這個物件

    def run(self):
        return self.x

m = magic('xx')
m.a = 'LANGZILANGZI'
print(m.a)
# 查詢實體的屬性
print(magic.a)
# 查詢類的屬性
print(m.x)
# 查詢實體的屬性

傳回結果:

 

'LANGZILANGZI'
'langzi'
'xx'

 

查詢順序是由下而上的查詢順序,init是初始化實體的屬性,要記住這裡使用magic.x是會報錯的,因為init是初始化實體,這個實體成為m,並不在屬於magic。

可能這樣舉例子不清晰,重新再看看程式碼

class magic:
    name = '浪子'
    def __init__(self,name):
        self.name = name

m = magic('langzi')
print(m.name)
print(magic.name)

傳回結果:

 

langzi
浪子

 

這樣是不是就比較清晰了,類中的name=’浪子’是屬於magic類當中的,實體m.name是屬於實體m當中的,是在類中init初始化的屬性。

他們的查詢順序是這樣:

  1. 找m.name的時候,由下而上,會先找到m。
  2. 找到m的初始話物件,從init開始查詢,就會找到初始化傳入的name
  3. 如果init中沒有name的話,就會往上走,查詢類中是不是存在name

就好像這樣的程式碼:

class magic:
    # def __init__(self,name):
    #     self.name = name
    name = '浪子'

m = magic()
print(m.name)
print(magic.name)

傳回結果:

 

浪子
浪子

 

三大方法

python類的呼叫有三大方法,分別是類方法,靜態方法,實體方法。這三個方法在曾經的文章有說過。

Python面向物件程式設計

這裡就不多做程式碼重寫,去原連結檢視學習即可。

資料封裝與私有屬性

私有屬性,也叫私有方法,是以雙下劃線開頭的命名變數。

無法透過實體方法和子類來呼叫的,只能透過類中寫的方法來呼叫。

比如:

class magic:
    __user = '浪子'

a = magic
print(magic.__user)
print(a.__user)

加了雙下劃線的user就是私有屬性,是沒法透過下麵兩種方式進行呼叫的,唯一可以呼叫這個私有屬性的方法就是使用類方法。

 

class magic:
    __user = '浪子'
    @classmethod
    def run(cls):
        print(cls.__user)

magic.run()

 

只有這樣才能呼叫類的私有屬性,這也就是對資料做了一個很好的封裝。

但是這樣的封裝並不是完全安全的,比如你看下麵的程式碼:

class magic:
    __user = '浪子'

m = magic
print(m._magic__user)

這樣能直接呼叫user,說白了這是一個小技巧python把私有變數偷偷隱藏起來變成了這樣子。

python的自省機制

自省:透過一定的機制,查詢到物件的內部結構

使用__dict__方法查詢類的屬性:

class magic:
    '我是註釋'
    user = '浪子'
    def run(age):
        print(age)

for x,y in magic.__dict__.items():
    print(x,':',y)

傳回結果:

 

__module__ : __main__
__doc__ : 我是註釋
user : 浪子
run : 0x0000018AB312CC80

>
__dict__ : ‘__dict__’ of ‘magic’ objects>
__weakref__ : ‘__weakref__’ of ‘magic’ objects>

 

透過dict來獲取類的內部結果,記住透過magic.__dict__[‘user’]=’小桃紅’也可以動態操作屬性。

不僅僅是dict,透過dir可以更加強大的列出該類的所有屬性。

super函式

super函式,呼叫父類。在類的繼承中,如果重定義某個方法,該方法會改寫父類的同名方法,但有時,我們希望能同時實現父類的功能,這時,我們就需要呼叫父類的方法了,可透過使用 super 來實現。

class A:
    def __init__(self,name):
        self.name = name
    def run(self):
        print(self.name+'6666666')

class B(A):
    def __init__(self,name):
        self.name = name
    def run(self):
        print(self.name+'7777777')
        super().run()
        #這裡是呼叫父類的run()方法
        # 還可以這樣super().__init__(name=name)這樣的格式

c = B('浪子')
c.run()

傳回物件:

浪子7777777
浪子6666666

事實上,super 和父類沒有實質性的關聯,super(cls, inst) 獲得的是 cls 在 inst 的 MRO 串列中的下一個類。MRO則是python中類繼承關係選擇的一種,有點像是廣度優先原則,可以print m.__mro__檢視。

    贊(0)

    分享創造快樂