您好,我是碼農飛哥,感謝您閱讀本文,歡迎一鍵三連哦,
本文主要介紹Python的封裝和多型這兩個重要特性,
干貨滿滿,建議收藏,需要用到時常看看, 小伙伴們如有問題及需要,歡迎踴躍留言哦~ ~ ~,
文章目錄
- 前言
- @property裝飾器
- Python的封裝機制
- super()函式
- 多繼承的情況
- type()函式
- 多型
- 列舉類
- 總結
- Python知識圖譜
前言
上一篇文章我們介紹了Python面向物件的一些基本概念,這一篇文章繼續總結Python面向物件的一些詳細知識點,本文主要介紹面向物件的封裝和多型兩個重要的特性,
@property裝飾器
當@property裝飾器修飾方法的時,就可以直接通過方法名來呼叫方法,而不需要加上后面的()小括號,其語法格式是:
@property
def 方法名(self)
代碼塊
其一般應用于要對類序列化的方法上,如下面Student類,
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
@property
def serialize(self):
return {"name": self.name, "score": self.score}
student = Student('張三', 100)
print(student.serialize)
Python的封裝機制
在Java的其他的面向物件的語言中,可以通過public,protected,private等訪問限制修飾符來表示一個方法可被訪問的范圍,在Python中沒有與之對應的訪問修飾符,Python中的變數和方法默認都是公有(public)的,說白了,就是誰都可以訪問,那么,在Python中有沒有一種機制來讓一個方法私有呢?答案是有的,
在Python中如果類中的變數或函式,其名稱以雙下劃線"__"開頭,則該變數(函式)為私有變數(私有函式)其屬性等同于private,私有方法的意思是,只能在類的內部訪問該方法,不能在類的外部訪問,
class Student2(object):
def __init__(self):
pass
def get_gender(self):
return self.__gender
def set_gender(self, gender):
self.__gender = gender
# 定義私有方法
def __display(self):
print(self.__gender)
student = Student2()
student.set_gender('男')
student.__display()
運行結果是:
Traceback (most recent call last):
File "/python_demo_1/demo/oop/Student2.py", line 36, in <module>
student.__display()
AttributeError: 'Student2' object has no attribute '__display'
如上代碼所示,直接訪問私有方法__display話會報錯,提示找不到__display方法,
需要注意的是:如果是類方法或者類變數的話,哪怕方法名前綴是有__修飾還是可以訪問,但是不建議這樣做,因為通過__修飾的話就默認是私有方法,
不過在python中方法名的前綴和后綴都有__修飾的方法是Python的內置方法,在自定義的方法中不建議這樣給方法命名,
super()函式
super函式用于子類繼承父類,并且重寫了父類的類實體方法或者構造方法時,如果此時要呼叫父類方法,可以通過super函式來呼叫,
class Animal:
def __init__(self, food):
self.food = food
class People(Animal):
def __init__(self, name, food):
super().__init__(food)
self.name = name
def say(self):
print("我是人,名字是:{0},吃的食物是:{1}".format(self.name, self.food))
people = People('張三', '熟食')
people.say()
運行結果是:我是人,名字是:張三,吃的食物是:熟食
如上代碼:People類繼承了Animal類,而Animal類中有個實體屬性food,在People類的構造方法中可以通過super().__init__(food)方法來呼叫其父類Animal類的構造方法實作對引數的注入,
多繼承的情況
Python是支持多繼承的,如果子類繼承的多個父類中包含同名的類實體方法,則子類物件在呼叫該方法時,會優先選擇排在最前面的父類的實體方法,顯然,構造方法 也是如此,使用super()函式,但如果涉及多繼承,該函式只能呼叫第一個直接父類的構造方法,
class People:
def __init__(self, name):
self.name = name
def say(self):
print("我是人,名字是:", self.name)
class Animal:
def __init__(self, food):
self.food = food
def display(self):
print("我是動物,我吃", self.food)
class Person(People, Animal):
# 自定義構造方法
def __init__(self, name, food):
super().__init__(name)
# super(Person,self).__init__(name)
# 呼叫其他父類的構造方法,需手動給self傳值
Animal.__init__(self, food)
per = Person('張三', '熟食')
per.say()
per.display()
運行結果是:
我是人,名字是: 張三
我是動物,我吃 熟食
type()函式
type()函式屬于Python內置函式,通常用來查看某個變數的具體型別,其高級的用法是創建一個自定義的型別(也就是創建一個類),其語法結構是:
type(obj)
type(name, bases, dict)
第一種語法格式是用來查看某個變數(類物件)的具體型別,obj表示某個變數或者類物件,
第二種語法用來創建類,其中name表示類的名稱,bases表示一個元組,其中存盤的是該類的父類;dict表示一個字典,用于表示類內部定義的屬性或者方法,
第一種語法舉個例子:
print(type(123) == type(456))
print(type(123) == int)
print(type('abc') == type(123))
運行結果是:
True
True
False
第二種語法舉個例子:
def say(self):
print('我要學Python!')
# 使用type()函式創建類
TypeTest = type("TypeTest", (object,), dict(say=say, name="碼農飛哥"))
# 創建一個TypeTest實體物件
typeTest = TypeTest()
typeTest.say()
print(typeTest.name)
運行結果是:
我要學Python!
碼農飛哥
如上通過type函式創造了一個名叫TypeTest的類,該類繼承于Object類,該類中定義一個方法say,一個類變數name,
多型
多型是繼封裝,繼承之后,面向物件的第三大特性,
在生活中,比如跑的動作,小貓,小狗和大象,跑起來是不一樣的;在比如飛的動作,昆蟲,鳥類和飛機,飛起來的動作也是不一樣的,可見,同一行為,通過不同的事物,可以體現出不同的形態,而多型就是用來描述這樣的狀態的,
多型需要滿足的兩個條件是:
- 繼承:多型一定是發生在子類和父類之間,
- 重寫:子類必須重寫父類的方法,
如下代碼:
class Animal(object):
def run(self):
print('動物奔跑')
class Dog(Animal):
def run(self):
print('小狗奔跑')
class Cat(Animal):
def run(self):
print('小貓奔跑')
animal=Animal()
animal.run()
animal = Dog()
animal.run()
animal = Cat()
animal.run()
運行結果是:
動物奔跑
小狗奔跑
小貓奔跑
Dog和Cat類都繼承了Animal類,并且這兩個類都重寫了Animal類的run方法,通過給變數animal賦值不同的物件再使其呼叫run方法時產生不同的效果,當然,這還不是多型的精髓,多型的精髓就是可以傳入不同的物件使其產生不同的效果,如下代碼所示,還是上面的那個例子,在此處定義一個WhoRun類,該類定義了一個run方法,在run方法中增加了一個who引數,
class WhoRun:
def run(self, who):
who.run()
class Animal(object):
def run(self):
print('動物奔跑')
class Dog(Animal):
def run(self):
print('小狗奔跑')
class Cat(Animal):
def run(self):
print('小貓奔跑')
a = WhoRun()
a.run(Animal())
a.run(Dog())
a.run(Cat())
運行結果是:
動物奔跑
小狗奔跑
小貓奔跑
通過向run方法中傳入不同的物件,然后通過傳入的物件來呼叫run方法以得到不同的效果,這就是著名的“鴨子模型”,
列舉類
針對一些具有特殊含義的類,其實體化物件的個數往往是固定的,比如用一個類表示月份,則該類的實體物件最多有12個;再比如用一個類表示季節,則該類的實體物件最多4個,再比如用一個類表示性別,則該類的實體物件最多2個,
from enum import Enum
class Color(Enum):
# 為序列值制定value值
red = 1
green = 2
blue = 3
# 獲取列舉類成員的3種方式
print(Color.red)
print(Color['red'])
print(Color(1))
# 調取列舉類成員的value和name
print(Color.red.value)
print(Color.red.name)
# 遍歷列舉類中所有成員的2種方式
for color in Color:
print(color)
運行結果是:
Color.red
Color.red
Color.red
1
red
Color.red
Color.green
Color.blue
總結
本文詳細介紹了Python類一些比較重要的知識點:比如多型,封裝等等,還介紹了列舉類都是在實際開發中會經常使用到的知識點,
Python知識圖譜
為了更好幫助更多的小伙伴對Python從入門到精通,我從CSDN官方那邊搞來了一套 《Python全堆疊知識圖譜》,尺寸 870mm x 560mm,展開后有一張辦公桌大小,也可以折疊成一本書的尺寸,有興趣的小伙伴可以了解一下------掃描下圖中的二維碼即可購買,

我本人也已經用上了,感覺非常好用,圖譜桌上放,知識心中留,

我是碼農飛哥,再次感謝您讀完本文,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/291485.html
標籤:python
下一篇:Python:羅馬數字轉整數
