#5 Python面向對象(四)

前言

本節將是Python面向對象的最後一篇博文了,這節將記錄類的特殊方法、特殊成員方法、舊類和新類的不一樣,以及一些其餘知識。Go!html

1、類的特殊方法

Python有三種特殊方法:實例方法、靜態方法、類方法。若是你讀過一些源代碼,你必定疑惑過這些代碼:@staticmethod、@classmethod,前面見到的全部方法都是實例方法,實例方法的第一個參數爲實例自己(self),因爲實例方法通過前面幾節已經掌握,全部本節將會熟悉剩下的兩種特殊方法安全

1.1 靜態方法

以前在類中編寫的各類方法其實都是屬於實例方法,每個方法的第一個參數是實例自己(self),實例方法當然好用,可是在開發中,須要一些這樣的方法:與類有關,在使用時不須要引用類和實例,也就是不能訪問類變量和實例變量。這些方法一般用來做全局的配置方法,使代碼更加簡潔和安全。函數

1.1.1 建立靜態方法

在類中的方法的前面使用裝飾器: @staticmethod 便可,靜態方法已經和普通函數沒有太大區別,惟一的區別就是靜態方法要經過對象來訪問,看例:spa

 1 class Teacher:
 2     def __init__(self, name, gender):
 3         self.name = name
 4         self.gender = gender
 5 
 6     def talk(self):
 7         print('I am {}'.format(self.name))
 8 
 9     @staticmethod    # 建立 is_man 靜態方法
10     def is_man(gender):
11         if gender == 'male':
12             return 1
13         return 0

經過上例能夠看到靜態方法的建立比較簡單,基本上已經和類無關了,按照普通的函數建立便可code

1.1.2 調用靜態方法

靜態方法與函數的區別就是調用方式不一樣,函數直接調用便可,可是靜態方法多多少少和類仍是有一些關係的,那就是調用時須要對象來調用:orm

zhangsan = Teacher('zhangsan', 'male')

print(zhangsan.is_man('male'))


# 運行結果:
1

注意:靜態方法沒法調用類變量和實例變量,這裏就不做演示了。htm

『防抄襲:讀者請忽略這段文字,文章做者是博客園的MinuteSheep對象

可是靜態方法一般並不會在類外調用靜態方法,而是直接在類內做爲全局配置方法使用,例如:blog

 1 class Teacher:
 2     def __init__(self, name, gender):
 3         self.name = name
 4         self.gender = gender
 5 
 6     def talk(self):
 7         print('I am {}'.format(self.name))
 8 
 9     @staticmethod
10     def is_man(gender):
11         if gender == 'male':
12             return 1
13         return 0
14 
15     def eat(self):
16         flag = self.is_man(self.gender)   # 做爲全局配置使用
17         if flag:
18             print('I am man, I will eat 2 buns')
19         else:
20             print('I am woman, I will eat 1 bun')
21 
22 
23 zhangsan = Teacher('zhangsan', 'male')
24 
25 zhangsan.eat()
# 運行結果:
I am man, I will eat 2 buns

1.1.3 繼承靜態方法

若是超類中有靜態方法時,子類繼承時會發生什麼呢?繼承

class Teacher(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

    @staticmethod
    def is_man(gender):
        if gender == 'male':
            return 1
        return 0

    def eat(self):
        flag = self.is_man(self.gender)   # 做爲全局配置使用
        if flag:
            print('I am {}, I will eat 2 buns'.format(flag))
        else:
            print('I am {}, I will eat 1 bun'.formar(flag))


class Chinese(Teacher):
    '''
    建立一個語文老師類,
    繼承Teacher
    '''

    def __init__(self, name, gender):
        super().__init__(name, gender)

    @staticmethod   # 改寫超類的靜態方法
    def is_man(gender):
        if gender == 'male':
            return 'man'
        return 'woman'


zhangsan = Chinese('zhangsan', 'male')

zhangsan.eat()

繼承後將超類靜態方法改寫,運行結果j將按照子類的靜態方法運行,結果以下:

# 運行結果:
I am man, I will eat 2 buns

# 而不是按照超類的靜態方法
# I am 1,I will eat 2 buns

1.2 類方法

 類方法,顧名思義是一種直接做用於類的方法。類方法和實例方法的區別就在於:類方法只能訪問類變量,不能訪問實例變量。

1.2.1 建立類方法

在類中的方法前面使用裝飾器: @classmethod 便可,類方法和實例方法格式類似,類方法第一個參數必須是類自己(cls),看例:

class Teacher(object):
    food = 'bun'

    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

    @classmethod   # 建立類方法 eat
    def eat(cls):
        print(cls.food)

經過上面代碼能夠看到,類方法的第一個參數爲類自己,習慣上用cls表示,固然也能夠用其餘單詞表示(這一點與self相似)

1.2.2 調用類方法

類方法的調用與實例方法無異,看例:

zhangsan = Teacher('zhangsan', 'male')
zhangsan.eat()


# 運行結果:
bun

注意:類方法只能調用類變量,不能調用實例變量,這裏就不做演示了

『防抄襲:讀者請忽略這段文字,文章做者是博客園的MinuteSheep

類方法常常出如今源代碼中,一般用來爲類傳入新的參數。

2、類的特殊成員方法

什麼事特殊成員方法呢?其實你已經見過了,那就是相似__init__這樣 __方法__ 形式的方法

2.1 經常使用的特殊成員方法

__init__   「構造函數,當實例化類對象時,會自動調用該方法」

class Test:
    def __init__(self):
        print('實例化類對象後就會運行我')

Test()

# 運行結果:
實例化類對象後就會運行我

__del__   「析構函數,當類對象在內存中被釋放時(也就是類對象運行完後),會自動調用該方法」

class Test:
    def __del__(self):
        print('類對象釋放後就會運行我')

Test()


# 運行結果:
類對象釋放後就會運行我

__call__   「call方法,在類或者對象後加括號執行該方法」

class Test:
    def __call__(self):
        print('我是博客園MinuteSheep,神馬文庫抄襲個人博文,不要臉')


Test()()
# 或者
# obj = Test()
# obj()

# 運行結果:
我是博客園MinuteSheep,神馬文庫抄襲個人博文,不要臉

__dict__   「dict方法,查看類或者對象的全部成員信息」

class Test:
x = 1000 y = 'MS' print(Test.__dict__) # 運行結果: {'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, 'x': 1000, '__doc__': None, 'y': 'MS', '__dict__': <attribute '__dict__' of 'Test' objects>}

__doc__   「doc方法,查看類的描述信息」

class Test:
    '''
    這裏是類的描述信息
    '''
    x = 1000
    y = 'MS'


print(Test.__doc__)


# 運行結果:

    這裏是類的描述信息

3、舊類與新類

Python3中,只有新類,舊類以及被移除, class 類名: 和 class 類名(object): 都是新類;Python2中, class 類名: 是舊類, class 類名(object): 是新類

對舊類和新類瞭解一下便可

3.1 舊類與新類的區別

舊類:深度優先

新類:廣度優先

 1 # 在Python2中
 2 
 3 
 4 class A:
 5     pass
 6 
 7 
 8 class B(A):
 9     pass
10 
11 
12 class C(B):
13     pass
14 
15 
16 class D(A, B, C):
17     pass
18 
19 
20 D()

在Python2中,上述代碼的調用順序爲:D->A->B->A->C->B->A

明顯是深度優先

 1 # 在Python2中
 2 
 3 
 4 class A(object):
 5     pass
 6 
 7 
 8 class B(A):
 9     pass
10 
11 
12 class C(B):
13     pass
14 
15 
16 class D(A, B, C):
17     pass
18 
19 
20 D()

在Python2中,上訴代碼的調用順序爲:D->A->B->C->A->B->A->object

明顯是廣度優先

4、其餘知識

4.1 私有成員和私有方法

接觸類這麼久了,你必定發現了又的方法和成員沒有下劃線,有的方法和成員只有一條下劃線,有的方法和成員首尾各有兩條下劃線,這究竟是什麼含義呢?

  • 無下劃線 foo:表示普通方法和成員

  • 一條下劃線 _foo:表示被保護方法和成員,不能被 from xxx import _foo 導入

  • 兩條下劃線 __foo:表示私有方法和成員,只運行類自己進行訪問

  • 首尾各兩條下劃線 __foo__:表示特殊方法,通常由系統自定義

結語

Python面向對象的知識到此結束,多加理解和聯繫才能真正掌握面向對象的知識,拜拜~

相關文章
相關標籤/搜索