高級特性

什么是對象
對象(Object)

既表示客觀世界問題空間中的某個具體事情仗岸,又表示軟件系統(tǒng)空間中的基本
元素

對象 = 屬性 + 方法

對象以id作為標(biāo)識戏锹,既包含數(shù)據(jù)(屬性)宋下,也包含代碼(方法)政模,是某一類具體事物的特殊實(shí)例笋熬。

對象是類的實(shí)例,是程序的基本單元

要創(chuàng)建一個新的對象菩鲜,首先必須定義一個類园细,用以指明該類型的對象所包含的內(nèi)容(屬性和方法)
同一類(class)的對象具有相同的屬性和方法,但屬性值和id不同接校。

對象名稱

賦值語句給予對象以名稱猛频,對象可以有對個名稱(變量引用),但只有一個id蛛勉。
例:a = complex(1, 2)

對象實(shí)現(xiàn)了屬性和方法的封裝鹿寻,是一種數(shù)據(jù)抽象機(jī)制

提高了軟件的重用性,靈活性诽凌,擴(kuò)展性

Python語言動態(tài)的特性毡熏,使得對象可以隨時增加或刪除屬性或方法
 例:  print(f.fx, f.fy)
      f.fz = 3.4
      print(f.fz) 
      del f.fz
面向?qū)ο缶幊?OOP)是一種程序設(shè)計(jì)范型,,同時也是皿淋、一種程序開發(fā)方法

程序中包含各種獨(dú)立而又能相互調(diào)用的對象招刹,每個對象都能接受恬试,處理數(shù)據(jù)并將數(shù)據(jù)傳遞給其他對象窝趣。

傳統(tǒng)程序設(shè)計(jì)

將程序看作一系列函數(shù)或指令的集合

類的定義與調(diào)用
什么是類
  • 類(class)是對象的模板,封裝了對應(yīng)現(xiàn)實(shí)實(shí)體的性質(zhì)和行為
  • 實(shí)例對象(Instance Object)是類的具體化
  • 把類比作模具训柴,對象則是用模具制造出來的零件
  • 類的出現(xiàn)為面向?qū)ο缶幊痰娜齻€最重要的特性提供了實(shí)現(xiàn)的手段(封裝性,繼承性,多態(tài)性)
類和函數(shù)相似哑舒,類是一系列代碼的封裝

Python中約定,類名用大寫字母開頭幻馁,函數(shù)用小寫字母開頭洗鸵,以便區(qū)分。

class語句:
class <類名>:
      <一系列方法的調(diào)用>
類的初始化
class <類名>:
      def __init__(self, <參數(shù)表>):
      def <方法名>(self, <參數(shù)表>):
  • _init_()是一個特殊的函數(shù)名仗嗦,用于根據(jù)類的定義創(chuàng)建實(shí)例對象膘滨,第一個參數(shù)必須是self
<類名>(<參數(shù)>)

調(diào)用類會創(chuàng)建一個對象,(注意括號~)
obj = <類名>(<參數(shù)表>)
返回一個對象實(shí)例
類方法中的self指這個對象實(shí)現(xiàn)~

使用點(diǎn)(.)操作符來調(diào)用對象里的方法
class Force: # 力
     def __init__(self, x, y): # x, y方向分量
         self.fx = x
         self.fy = y
    def show(self): # 打印出力的值
        print("Force<%s, %s>"%(self.fx, self.fy))
    def add(selfl, force2):
        x = self.fx + force2.fx
        y = self.fy + force2.fy
        return Force(x, y)

# 生成一個力對象
f1 = Force(0, 1)
f1.show()
# 生成另一個力的對象
f2 = Force(3, 4)
# 合成為新的力
f3 = f1.add(f2)
f3.show()
類定義中的特殊的方法
特殊方法(special method)

也被稱作魔術(shù)方法(magic method)
在類定義中實(shí)現(xiàn)一些特殊方法稀拐,可以方便的使用Python中一些內(nèi)置操作
所有特殊方法的名稱以兩個(__)開始和結(jié)束

對象構(gòu)造器 __init__(self, [...)實(shí)例化對象時調(diào)用
對象析構(gòu)器 __del__(self, [...)
from os.path import join
class FileObject:
      '''給文件對象進(jìn)行包裝從而確認(rèn)在刪除是文件流被關(guān)閉 '''
      def __init__(self, filepath=’~‘, filename='sample.txt'):
          # 讀寫模式打開一個文件
          self.file = open(join(filepath, filename), 'r+')

      def __del__(self):
          self.file.close()
          del self.file
算術(shù)操作符
__add__(self, other): 使用+操作符
__sub__(self, other): 使用-操作符
__mul__(self, other): 使用*操作符
__div__(self, other): 使用/操作符
反運(yùn)算
當(dāng)左操作數(shù)不支持相應(yīng)的操作是被調(diào)用
__radd__(self, other)
__rsub__(self, other)
__rmul__(self, other)
__rdiv__(self, other)
大小比較
__eq__(self, other): 使用 == 操作符
__ne__(self, other): 使用 != 操作符
__lt__(self, other): 使用 < 操作符
__gt__(self, other): 使用 > 操作符
__le__(self, other): 使用 <= 操作符
__ge__(self, other): 使用 >= 操作符

例子:

class Force: # 力
     def __init__(self, x, y): # x, y方向分量
         self.fx = x
         self.fy = y
    def show(self): # 打印出力的值
        print("Force<%s, %s>"%(self.fx, self.fy))
    def add(selfl, force2):
        x = self.fx + force2.fx
        y = self.fy + force2.fy
        return Force(x, y)
    __add__ =  add
    def __str__(self):
        return ”F<%s, %s>“%(self.fx, self.fy)
    def __mul__(self):
        x, y = self.fx * n, self.fy * n
        return Force(x, y)
    def __eq__(self, force2):
        return (self.fx == force2.fx) and (self.fy == force2.fy)

# 操作符使用
f3 = f1 + f2
print("Fadd = %s"%(f3,))
f3 = f1 * 4.5
print("Fmul = %s"%(f3,))
print("%s == %s? ->%s"%(f1, f2, f1 == f2))
字符串操作
不僅數(shù)字類型可以使用+(__add__())和-(__sub__())的數(shù)學(xué)運(yùn)算符火邓,例如字符串類型可以使用+進(jìn)行拼接,使用*進(jìn)行復(fù)制
__str__(self): 自動轉(zhuǎn)換為字符串
__repr__(self): 返回一個用來表示對象的字符串
__len__(self): 返回元素個數(shù)
自定義對象的排序
列表排序 sort()

對原列表進(jìn)行排序,改變原列表內(nèi)容铲咨。
如果列表中的元素都是數(shù)字躲胳,默認(rèn)按升序排序
通過添加參數(shù)recerse=True可改變?yōu)榻敌蚺判?br> 如果元素都是字符串,則會按照字母表順序排序

>>> num = [4, 2, 7, 0,1]
>>> num.sort()
[0, 1, 2, 4, 7]
>>> num.sort(reverse = True)
>>> num
[7, 4, 2, 1, 0]
>>> name = ['John', 'Connor', 'Bruce', 'Arthur', 'Edward']
>>> name.sort()
>>> name
['Arthur', 'Bruce', 'Connor', 'Edward', 'John']
通用函數(shù) sorted()

類似sort()纤勒,但返回的是排好序的列表副本坯苹,原列表內(nèi)容不變

>>> name = ['John', 'Connor', 'Bruce', 'Arthur', 'Edward']
>>> sorted_name = sorted(name)
>>> sorted_name
['Arthur', 'Bruce', 'Connor', 'Edward', 'John']
>>> name
['John', 'Connor', 'Bruce', 'Arthur', 'Edward']

只有當(dāng)列表中的所有元素都是同一種類型的時候,sort()和sorted()才會正常工作

特殊方法 __lt__(less than)

由于Python的可擴(kuò)展性摇天,每種數(shù)據(jù)類型可以定義特殊方法
def __lt__(self, y)
返回True視為比y小粹湃,排在前
返回False視為比y大,排在后
只要類定義了特殊方法__lt__泉坐,任何自定義類都可以使用 x < y 這樣比較再芋。

class Student:
    def __init__(self, name, grade):
       self.name = name, self.grade = grade
    # 內(nèi)置sort()函數(shù)只引用 < 比較符來判斷前后
    def __lt__(self, other):
        # 成績比other高的,排在它前面
        return self.grade > other.grade
    # Student 的易讀字符串表示
    def __str__(self):
        return "Student(%s, %s)"%(self.name, self.grade)
    # Student的正式字符串表示坚冀,我們讓它跟易讀表示相同
    __repr__ = __str__

# 構(gòu)造一個列表济赎,加入Student對象
s = list()
# 添加Student對象到list中
s.append(Student("Jack", 80))
s.append(Student("Jane", 75))
s.append(Student("Smith", 82))
s.append(Student("Cook", 90))
s.append(Student("Tom", 70))
print("Original: ", s)
# 對list進(jìn)行排序,注意這里是內(nèi)置sort()方法
s.sort()
# 查看結(jié)果记某,已經(jīng)是按照成績排好序了
print("Sorted: ", s)
>>> Original: [("Jack", 80), ("Jane", 75), ("Smith", 82), ("Cook", 90), ("Tom", 70)]
>>> Sorted: [("Cook", 90), ("Smith", 82), ("Jack", 80), ("Jane", 75), ("Tom", 70)]
>>> s[0] < s[1]
True

直接調(diào)用列表sort方法司训,可以根據(jù) __lt__定義排序。
直接檢驗(yàn) Student 對象的大小 s[i] < s[j]
另外可以定義其他比較符 __gt__等(大于液南,小于壳猜,不等于···)

類的繼承

繼承(inheritance):如果一個類A繼承自另一個類B,就把A稱為子類滑凉,被繼承的B稱為父類(基類统扳,超類)
代碼復(fù)用:利用繼承可以從已有類中衍生出新的類,添加或修改部分功能畅姊。
新類具有舊類中的各種屬性和方法咒钟,而不需要進(jìn)行任何復(fù)制。

類的繼承機(jī)制
class Car:
    def __init__(self, name):
        self.name = name
        self.remain_mille = 0
    def fill_fuel(self, miles): # 加燃料里程
        self.remain_mile = miles
    def run(self, miles): # 跑miles英里
        print(self.name, end=": ")
        if self.remain_mile >= miles:
            self.remain_mile -= miles
            print("run %d miles!"%(miles,))
        else:
            print("fuel out!")

class GasCar(Car):
    def fill_fuel(self, gas): # 加汽油gas升
        self.remain_mile = gas *6.0 # 每升跑6英里

class ElecCar(Car):
    def fill_fuel(self, power): # 充電power度
        self.remain_mile = power * 3.0 # 每度電跑3英里

gcar = GasCar("BMW")
gcar.fill_fuel(50.0)
gcar.run(200.0)
>>> BMW: run 200 miles!
ecar = ElecCar("Tesla")
ecar.fill_fuel(60.0)
ecar.run(200.0)
>>> Tesla: fule out!
子類與父類

定義:如果兩個類具有“一般 -- 特殊”的邏輯關(guān)系若未,那么特殊類就可以作為一般類的“子類”來定義朱嘴,從“父類”繼承屬性的方法

class <子類名>(<父類名>):
    def <重定義方法>(self, ...)

覆蓋(Override)
子類對象可以調(diào)用父類方法,除非這個方法在子類中重新定義了粗合。
如果子類同名方法覆蓋了父類的方法萍嬉,仍然還可以調(diào)用父類的方法。
子類還可以添加父類中沒有的方法和屬性

class GasCar(Car):
    def __init__(self, name, capacity): # 名稱和排量
        super().__init__(name) # 父類初始化方法隙疚,只有名稱
        self.capacity = capacity
關(guān)于self

在類定義中壤追,所有方法的首個參數(shù)一般都是self
self的作用:在類內(nèi)部,實(shí)例化過程中傳入的所有數(shù)據(jù)都賦給這個變量供屉。
self實(shí)際上代表對象實(shí)例

<對象>.<方法>(<參數(shù)>) 等價(jià)于 <類>.<方法>(<對象>, <參數(shù)>)
gcar = GasCar("BMW")
gcar.fill_fuel(50.0)
gcar.fun(200.0)  # 這里
GasCar.run(gcar, 200.0) # 和這里是等價(jià)的
異常處理
try-except語句
try:
    <檢測語句>
except <錯誤類型> [as e]:
    <異常處理>
try-finally語句
try:
    <檢測語句>
except <錯誤類型> [as e]:
    <異常處理>
finally:
    <語句塊>
else語句
try:
    <檢測語句>
except <錯誤類型> [as e]:
    <異常處理>
else:
    <語句塊>
else: # 沒有出錯執(zhí)行的代碼

例子

try:
    print("try...")
    r = 10 / 'xyz'
    print("result: ", r)
except TypeError as e:
    print("TypeError:", e)
except ZeroDivisionError as e:
    print("ZeroDivisionError:", e)
else:
    print("no error!")
finally:
    print("finally...")
print("END")
>>>try...
TypeError: unsupported operand type(s) for /: 'int' and 'str'
finally...
END
推導(dǎo)式
什么是推導(dǎo)式

推導(dǎo)式是從一個或者多個迭代器快速簡潔地創(chuàng)建數(shù)據(jù)結(jié)構(gòu)的一種方法行冰。
將循環(huán)和條件判斷結(jié)合捅厂,從而避免語法冗長的代碼。
可以用來生列表资柔,字典和集合焙贷。

列表推導(dǎo)式
[<表達(dá)式> for <變量> in <可迭代對象> if <邏輯條件>]
[x**x for x in range(10)]
[x+y for x in range(10) for y in range(10)]
[x*x for x in range(10) if x % 2 == 0]
[x.upper() for x in [1, ‘a(chǎn)’, 'b', True] if isinstance(x, str)]
>>> ['A', 'B']
字典推導(dǎo)式
{<表達(dá)式>:<元素表達(dá)式> for <變量> in <可迭代對象> if <邏輯條件>}
{"k%s"%(x,):x**3 for x in range(10)}
集合推導(dǎo)式
{<元素表達(dá)式> for <變量> in <可迭代對象> if <邏輯條件>}
{x**3 for x in range(10)}
生成器推導(dǎo)式

返回一個生成器對象,也是可迭代對象贿堰。
但生成器并不會立即產(chǎn)生全部元素辙芍,僅在要用到元素的時候才會生成,可以極大節(jié)省內(nèi)存羹与。

(<元素表達(dá)式> for  <變量> in <可迭代對象> if <邏輯條件>)
>>> agen = (x**x for x in range(3))
>>> agen
<generator object <genexpr> at 0x1078f5620>
>>> for i in agen:
        print(i)
0
1
2
生成器函數(shù)
什么是生成器

生成器(generator)是用來創(chuàng)建數(shù)據(jù)序列的一種對象故硅。
使用它可以迭代龐大的序列,且不需要在內(nèi)存中創(chuàng)建和儲存整個序列纵搁、
通常生成器是為迭代器產(chǎn)生數(shù)據(jù)的吃衅。
如果要創(chuàng)建一個比較大的序列,生成器推導(dǎo)式將會比較復(fù)雜腾誉,一行表達(dá)式無法容納徘层,這是可以定義生成器函數(shù)。

生成器函數(shù)與普通函數(shù)

生成器函數(shù)的定義與普通函數(shù)相同利职,只是將return 換成 yield趣效。

yield 與 return
  • yeild 語句
    立即返回一個值
    下一下迭代生成器函數(shù)時,從yeild語句后的語句繼續(xù)執(zhí)行猪贪,直到再次yield返回跷敬,或終止。
  • return 語句
    終止函數(shù)的執(zhí)行热押,下次調(diào)用會重新執(zhí)行函數(shù)西傀。
協(xié)同程序

可以運(yùn)行的獨(dú)立函數(shù)調(diào)用,函數(shù)可以暫屯把ⅲ或掛起拥褂,并在需要的時候從離開的地方繼續(xù)或重新開始。

def even_number(max):
    n = 0
    while n < max:
        yield n
        n += 2
for i in even_number(10):
    print(i)
0
2
4
6
8
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鬼廓,一起剝皮案震驚了整個濱河市肿仑,隨后出現(xiàn)的幾起案子致盟,更是在濱河造成了極大的恐慌碎税,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馏锡,死亡現(xiàn)場離奇詭異雷蹂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杯道,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門匪煌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來责蝠,“玉大人,你說我怎么就攤上這事萎庭∷剑” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵驳规,是天一觀的道長肴敛。 經(jīng)常有香客問我,道長吗购,這世上最難降的妖魔是什么医男? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮捻勉,結(jié)果婚禮上镀梭,老公的妹妹穿的比我還像新娘。我一直安慰自己踱启,他們只是感情好报账,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著埠偿,像睡著了一般笙什。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胚想,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天琐凭,我揣著相機(jī)與錄音,去河邊找鬼浊服。 笑死统屈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牙躺。 我是一名探鬼主播愁憔,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼孽拷!你這毒婦竟也來了吨掌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤脓恕,失蹤者是張志新(化名)和其女友劉穎膜宋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炼幔,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秋茫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乃秀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肛著。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡圆兵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出枢贿,到底是詐尸還是另有隱情殉农,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布局荚,位于F島的核電站统抬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏危队。R本人自食惡果不足惜聪建,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茫陆。 院中可真熱鬧金麸,春花似錦、人聲如沸簿盅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桨醋。三九已至棚瘟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喜最,已是汗流浹背偎蘸。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞬内,地道東北人迷雪。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像虫蝶,于是被迫代替她去往敵國和親章咧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容