類
Python中,類的命名使用帕斯卡命名方式,即首字母大寫。
Python中定義類的方式如下:
class 類名([父類名[,父類名[,...]]]): pass
省略父類名表示該類直接繼承自object,類的實例化如下:
class Person(): def __init__(self): pass person=Person()
__init__()是類的構造函數,在實例化時調用,它的參數self表示類實例。
類中的字段
字段的訪問級別:
- Python中以雙下划線開頭的字段訪問級別是private;
- Python中以下划線開頭的字段訪問級別是protected;
- Python中未以下划線開頭的字段的訪問級別是public;
上述訪問級別更多的是一種編程約定,即便是以雙下划線開頭的字段,在類的外部也是可以訪問的,但不建議這么做。示例代碼如下:
class Person(): age = 24 _name = 'person' __family_name = 'securate' def __init__(self): print('Person init')
Person類成員:
在上圖中,我們可以看到類中並沒有出現一雙下划線開頭的字段__family_name,而多出一個_Person__family_name。說明類實例不可以直接訪問__family_name,但可以通過實例名._Person__family_name的方式來訪問。
上述三種類型的變量均可以通過類或類實例進行訪問。通過self定義的變量只能通過類實例進行訪問,如self.country,變量country只能通過類實例進行訪問。
類中的方法
Python中方法名均為小寫字母,不同單詞間以下划線進行分割。
方法的覆蓋
Python類中沒有方法的重載,對於具有相同名稱的方法,后面的定義會覆蓋掉前面的定義;子類會覆蓋父類中同名的方法。在Person類中定義兩個同名方法say:
def say(self, message): print(message) def say(self, info): print('second: '+info) person=Person() person.say('invoke')
程序執行結果:
從程序運行結果可知,調用的是定義在后面的say(self, info)方法。
特殊方法
以雙下划線開頭和結尾的方法屬於特殊方法,如:__init__(self)、__call__(self)等內置方法。在我們自己定義方法時不建議采取這種方式。
方法的訪問級別
- Python中以雙下划線開頭的方法訪問級別是private;
- Python中以下划線開頭的方法訪問級別是protected;
- Python中未以下划線開頭的方法的訪問級別是public;
和字段類似,上述訪問級別也只是一種編程約定,即便是以雙下划線開頭的方法,在類的外部也是可以訪問的,但不建議這么做。
實例方法
定義方法時,沒有裝飾器修飾且帶有參數的(可以不是self),即為實例方法。
類外部通過類實例來調用,類內部通過self.方法名來調用。
def method(self): pass
@classmethod
@classmethod是Python中的裝飾器。
使用@classmethod修飾的方法,必須要帶參數(默認參數名是cls),該參數表示類自身。可以通過類自身或者類實例調用@classmethod修飾的方法。在@classmethod修飾的方法中無法訪問實例成員,但可以通過cls或者類名訪問類中的字段。
@staticmethod
使用@staticmethod修飾的方法可以沒有參數,可以通過類或者類實例調用。在@staticmethod修飾的方法中,無法訪問類中的實例成員,可以通過類名訪問類中的字段。
繼承
定義一個Chinese類,繼承自Person類:
class Chinese(Person): def __init__(self): pass chinese=Chinese()
Chinese中的字段:
從Chinese類型的實例中,我們可以看到Chinese類繼承了除country之外的所有字段。
子類還會繼承父類中的函數,若子類沒有實現自己的構造函數(__init__(self)),那么在實例化子類時會調用父類的構造函數。
子類間的類型轉換
class Person(): def __init__(self): pass def convert(self, class_type): if issubclass(class_type, Person): return (class_type)(self) class Chinese(Person): def __init__(self, convert=None): pass def cn_method(self): print('chinese') class Japanese(Person): def __init__(self, convert=None): pass
執行類型轉換:
jap = Japanese() cn = jap.convert(Chinese) cn.cn_method()
類型轉換結果如下圖:
可以看到,根據Japanese實例得到了Chinese類型實例。這里的轉換只是獲取了Chinese類型的實例cn,而原有的Japanese類型實例依然存在於內存中。
程序執行結果如下圖:
推薦閱讀
參考文章:
飄逸的python - @staticmethod和@classmethod的作用與區別
Difference between @staticmethod and @classmethod in Python
