国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python學習Day9property多重繼承Mixin

2019-11-14 17:14:32
字體:
來源:轉載
供稿:網友

在綁定屬性時,如果我們直接把屬性暴露出去,雖然寫起來很簡單,但是,沒辦法檢查參數,導致可以把成績隨便改:

s = Student()

s.score = 9999

為了限制score的范圍,可以通過一個set_score()方法來設置成績,再通過一個get_score()來獲取成績,這樣,在set_score()方法里,就可以檢查參數:

class Student(object):

 

def get_score(self):

return self._score

 

def set_score(self, value):

if not isinstance(value, int):

raise ValueError('score must be an integer!')

if value < 0 or value > 100:

raise ValueError('score must between 0 ~ 100!')

self._score = value

>>> s = Student()

>>> s.set_score(60) # ok!

>>> s.get_score()

60

>>> s.set_score(9999)

Traceback (most recent call last):

...

ValueError: score must between 0 ~ 100!

Python內置的@PRoperty裝飾器負責把一個方法變成屬性調用:

class Student(object):

 

@property

def score(self):

return self._score

 

@score.setter

def score(self, value):

if not isinstance(value, int):

raise ValueError('score must be an integer!')

if value < 0 or value > 100:

raise ValueError('score must between 0 ~ 100!')

self._score = value

@property的實現比較復雜,我們先考察如何使用。把一個getter方法變成屬性,只需要加上@property就可以了,此時,@property本身又創建了另一個裝飾器@score.setter,負責把一個setter方法變成屬性賦值,于是,我們就擁有一個可控的屬性操作:

>>> s = Student()

>>> s.score = 60 # OK,實際轉化為s.set_score(60)

>>> s.score # OK,實際轉化為s.get_score()

60

>>> s.score = 9999

Traceback (most recent call last):

...

ValueError: score must between 0 ~ 100!

定義只讀屬性,只定義getter方法,不定義setter方法就是一個只讀屬性:

class Student(object):

 

@property

def birth(self):

return self._birth

 

@birth.setter

def birth(self, value):

self._birth = value

 

@property

def age(self):

return 2014 - self._birth

多重繼承

繼承是面向對象編程的一個重要的方式,因為通過繼承,子類就可以擴展父類的功能。

首先,主要的類層次仍按照哺乳類和鳥類設計:

class Animal(object):

pass

 

# 大類:

class Mammal(Animal):

pass

 

class Bird(Animal):

pass

 

# 各種動物:

class Dog(Mammal):

pass

 

class Bat(Mammal):

pass

 

class Parrot(Bird):

pass

 

class Ostrich(Bird):

pass

給動物再加上Runnable和Flyable的功能,只需要先定義好Runnable和Flyable的類:

class Runnable(object):

def run(self):

print('Running...')

 

class Flyable(object):

def fly(self):

print('Flying...')

對于需要Runnable功能的動物,就多繼承一個Runnable,例如Dog:

class Dog(Mammal, Runnable):

pass

對于需要Flyable功能的動物,就多繼承一個Flyable,例如Bat:

 

class Bat(Mammal, Flyable):

pass

通過多重繼承,一個子類就可以同時獲得多個父類的所有功能。

 

Mixin

在設計類的繼承關系時,通常,主線都是單一繼承下來的,例如,Ostrich繼承自Bird。但是,如果需要“混入”額外的功能,通過多重繼承就可以實現,比如,讓Ostrich除了繼承自Bird外,再同時繼承Runnable。這種設計通常稱之為Mixin。

 

為了更好地看出繼承關系,我們把Runnable和Flyable改為RunnableMixin和FlyableMixin。類似的,你還可以定義出肉食動物CarnivorousMixin和植食動物HerbivoresMixin,讓某個動物同時擁有好幾個Mixin:

 

class Dog(Mammal, RunnableMixin, CarnivorousMixin):

pass

Mixin的目的就是給一個類增加多個功能,這樣,在設計類的時候,我們優先考慮通過多重繼承來組合多個Mixin的功能,而不是設計多層次的復雜的繼承關系。

 

Python自帶的很多庫也使用了Mixin。舉個例子,Python自帶了TCPServer和UDPServer這兩類網絡服務,而要同時服務多個用戶就必須使用多進程或多線程模型,這兩種模型由ForkingMixin和ThreadingMixin提供。通過組合,我們就可以創造出合適的服務來。

 

比如,編寫一個多進程模式的TCP服務,定義如下:

 

class MyTCPServer(TCPServer, ForkingMixin):

pass

編寫一個多線程模式的UDP服務,定義如下:

 

class MyUDPServer(UDPServer, ThreadingMixin):

pass

如果你打算搞一個更先進的協程模型,可以編寫一個CoroutineMixin:

 

class MyTCPServer(TCPServer, CoroutineMixin):

pass

Try

這樣一來,我們不需要復雜而龐大的繼承鏈,只要選擇組合不同的類的功能,就可以快速構造出所需的子類。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 渑池县| 大宁县| 建德市| 定结县| 勐海县| 农安县| 诸城市| 彝良县| 库伦旗| 诸城市| 宁乡县| 武穴市| 郸城县| 云梦县| 外汇| 永泰县| 扶绥县| 忻州市| 襄垣县| 红河县| 连云港市| 高碑店市| 东海县| 镇坪县| 上栗县| 柳州市| 阳朔县| 聂荣县| 罗城| 岫岩| 镇沅| 南皮县| 江安县| 吴川市| 灵川县| 鲜城| 京山县| 阳原县| 沅江市| 元江| 类乌齐县|