2020-02-02python學(xué)習(xí)記錄(3)-函數(shù)式編程&模塊

四倡缠、函數(shù)式編程:

函數(shù)式編程,有利于代碼的管理迫皱,后期的代碼的迭代和修改矫钓。函數(shù)的封裝參數(shù)的傳遞,返回值的返回舍杜。

高階函數(shù):

變量可以指向函數(shù)新娜、函數(shù)名也可能是變量(abs取絕對(duì)值)

def add(x, y, f):

? ? return f(x) + f(y)

把函數(shù)作為參數(shù)傳入,這樣的函數(shù)稱為高階函數(shù)既绩,函數(shù)式編程就是指這種高度抽象的編程范式概龄。

map/reduce:

Python內(nèi)建了map()和reduce()函數(shù)。

map()函數(shù)接收兩個(gè)參數(shù)饲握,一個(gè)是函數(shù)私杜,一個(gè)是Iterable蚕键,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回衰粹。

map()傳入的第一個(gè)參數(shù)是mix锣光,即函數(shù)對(duì)象本身。由于結(jié)果r是一個(gè)Iterator铝耻,Iterator是惰性序列誊爹,因此通過(guò)list()函數(shù)讓它把整個(gè)序列都計(jì)算出來(lái)并返回一個(gè)list。

一個(gè)序列求和瓢捉,就可以用reduce實(shí)現(xiàn):

運(yùn)算可以直接用Python內(nèi)建函數(shù)sum()频丘,沒(méi)必要?jiǎng)佑胷educe。

filter:

Python內(nèi)建的filter()函數(shù)用于過(guò)濾序列泡态。

通過(guò)filter去除某些不需要的值

只保留偶數(shù)

filter()的作用是從一個(gè)序列中篩出符合條件的元素搂漠。由于filter()使用了惰性計(jì)算,所以只有在取filter()結(jié)果的時(shí)候某弦,才會(huì)真正篩選并每次返回下一個(gè)篩出的元素桐汤。

sorted:

主要是排序:

sorted()也是一個(gè)高階函數(shù)。用sorted()排序的關(guān)鍵在于實(shí)現(xiàn)一個(gè)映射函數(shù)靶壮。

要進(jìn)行反向排序怔毛,不必改動(dòng)key函數(shù),可以傳入第三個(gè)參數(shù)reverse=Trues

sorted傳入key函數(shù)亮钦,即可實(shí)現(xiàn)忽略大小寫(xiě)的排序:

返回函數(shù):

高階函數(shù)除了可以接受函數(shù)作為參數(shù)外,還可以把函數(shù)作為結(jié)果值返回充活。

def lazy_sum(*args):? ? def sum():? ? ? ? ax = 0? ? ? ? for n in args:? ? ? ? ? ? ax = ax + n? ? ? ? return ax? ? return sum

匿名函數(shù):

在傳入函數(shù)時(shí)蜂莉,有些時(shí)候,不需要顯式地定義函數(shù)混卵,直接傳入匿名函數(shù)更方便映穗。

list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

相當(dāng)于下面的代碼:

轉(zhuǎn)換代碼:

def is_odd(n):? ? return n % 2 == 1? L = list(filter(is_odd, range(1, 20)))? x = list(filter(lambda x: x % 2 == 1, range(1,20))) print(x)

裝飾器:

由于函數(shù)也是一個(gè)對(duì)象,而且函數(shù)對(duì)象可以被賦值給變量幕随,所以蚁滋,通過(guò)變量也能調(diào)用該函數(shù)。

#!/usr/bin/env python3 # -*- coding: utf-8 -*-? import time, functools? def metric(fn):? ? print('%s executed in %s ms' % (fn.__name__, 10.24))? ? return fn? @metric def fast(x, y):? ? time.sleep(0.0012)? ? return x + y;? @metric def slow(x, y, z):? ? time.sleep(0.1234)? ? return x * y * z;? if __name__ == '__main__':? f = fast(11, 22)? s = slow(11, 22, 33)

偏函數(shù):

Python的functools模塊提供了很多有用的功能赘淮,其中一個(gè)就是偏函數(shù)(Partial function)辕录。

int()函數(shù)還提供額外的base參數(shù),默認(rèn)值為10梢卸。如果傳入base參數(shù)走诞,就可以做N進(jìn)制的轉(zhuǎn)換:

五、模塊:

注意:自己創(chuàng)建模塊時(shí)要注意命名蛤高,不能和Python自帶的模塊名稱沖突蚣旱。例如碑幅,系統(tǒng)自帶了sys模塊,自己的模塊就不可命名為sys.py塞绿,否則將無(wú)法導(dǎo)入系統(tǒng)自帶的sys模塊沟涨。

使用模塊:

Python本身就內(nèi)置了很多非常有用的模塊,只要安裝完畢异吻,這些模塊就可以立刻使用裹赴。

#!/usr/bin/env python3 # -*- coding: utf-8 -*-? ' a test module '? __author__ = 'Michael Liao' __age__ = '23'? import sys? def test():? ? args = sys.argv? ? if len(args)==1:? ? ? ? print('Hello, %s!' % args[0])? ? elif len(args)==2:? ? ? ? print('Hello, %s!' % args[1])? ? else:? ? ? ? print('Too many arguments!')? if __name__=='__main__':? ? test()

作用域:

在一個(gè)模塊中,我們可能會(huì)定義很多函數(shù)和變量涧黄,但有的函數(shù)和變量我們希望給別人使用篮昧,有的函數(shù)和變量我們希望僅僅在模塊內(nèi)部使用。在Python中笋妥,是通過(guò)_前綴來(lái)實(shí)現(xiàn)的懊昨。

正常的函數(shù)和變量名是公開(kāi)的(public),可以被直接引用春宣,比如:abc酵颁,x123,PI等月帝;

類似_xxx和__xxx這樣的函數(shù)或變量就是非公開(kāi)的(private)躏惋,不應(yīng)該被直接引用,比如_abc嚷辅,__abc等簿姨;

安裝第三方模塊:

在Python中,安裝第三方模塊簸搞,是通過(guò)包管理工具pip完成的扁位。

六、面向?qū)ο缶幊?/p>

主要是抽象對(duì)象的一些特性趁俊,實(shí)例化具體的一個(gè)里面的一個(gè)處理域仇。

在Python中,所有數(shù)據(jù)類型都可以視為對(duì)象寺擂,當(dāng)然也可以自定義對(duì)象暇务。自定義的對(duì)象數(shù)據(jù)類型就是面向?qū)ο笾械念悾–lass)的概念。

可以類比java的編程

類和實(shí)例:

面向?qū)ο笞钪匾母拍罹褪穷悾–lass)和實(shí)例(Instance)怔软,必須牢記類是抽象的模板垦细,比如Student類,而實(shí)例是根據(jù)類創(chuàng)建出來(lái)的一個(gè)個(gè)具體的“對(duì)象”挡逼,每個(gè)對(duì)象都擁有相同的方法蝠检,但各自的數(shù)據(jù)可能不同。

class Student(object):? ? pass

class后面緊接著是類名挚瘟,即Student叹谁,類名通常是大寫(xiě)開(kāi)頭的單詞饲梭,緊接著是(object),表示該類是從哪個(gè)類繼承下來(lái)的焰檩,繼承的概念后面再講憔涉,通常,如果沒(méi)有合適的繼承類析苫,就使用object類兜叨,這是所有類最終都會(huì)繼承的類。

數(shù)據(jù)封裝:

面向?qū)ο缶幊痰囊粋€(gè)重要特點(diǎn)就是數(shù)據(jù)封裝衩侥。在上面的Student類中国旷,每個(gè)實(shí)例就擁有各自的name和score這些數(shù)據(jù).

>>> class stu(object):

...? ? def __init__(self,name,age):

...? ? ? ? ? ? self.name = name

...? ? ? ? ? ? self.age = age

...

>>> lisa = stu('lisa',12)

>>> lisa.name

'lisa'

訪問(wèn)限制:

在Class內(nèi)部,可以有屬性和方法茫死,而外部代碼可以通過(guò)直接調(diào)用實(shí)例變量的方法來(lái)操作數(shù)據(jù)跪但,這樣,就隱藏了內(nèi)部的復(fù)雜邏輯峦萎。

如果要讓內(nèi)部屬性不被外部訪問(wèn)屡久,可以把屬性的名稱前加上兩個(gè)下劃線__,在Python中爱榔,實(shí)例的變量名如果以__開(kāi)頭被环,就變成了一個(gè)私有變量(private),只有內(nèi)部可以訪問(wèn)详幽,外部不能訪問(wèn)筛欢,所以,我們把Student類改一改:

>>> class stu(object):

...? ? def __init__(self,name,age):

...? ? ? ? ? ? self.__name = name

...? ? ? ? ? ? self.__age = age

...

前面添加兩個(gè)__這個(gè)就不能外部修改內(nèi)容:

改完后唇聘,對(duì)于外部代碼來(lái)說(shuō)版姑,沒(méi)什么變動(dòng),但是已經(jīng)無(wú)法從外部訪問(wèn)實(shí)例變量.__name和實(shí)例變量.__age了:

>>> bart = Student('Bart Simpson', 59)

>>> bart.__name

Traceback (most recent call last):

? File "<stdin>", line 1, in <module>

AttributeError: 'Student' object has no attribute '__name'

雙下劃線開(kāi)頭的實(shí)例變量是不是一定不能從外部訪問(wèn)呢雳灾?其實(shí)也不是漠酿。不能直接訪問(wèn)__name是因?yàn)镻ython解釋器對(duì)外把__name變量改成了_Student__name冯凹,所以谎亩,仍然可以通過(guò)_Student__name來(lái)訪問(wèn)__name變量:

繼承和多態(tài):

在OOP程序設(shè)計(jì)中,當(dāng)我們定義一個(gè)class的時(shí)候宇姚,可以從某個(gè)現(xiàn)有的class繼承匈庭,新的class稱為子類(Subclass),而被繼承的class稱為基類浑劳、父類或超類(Base class阱持、Super class)。

#!/usr/bin/env python3 # -*- coding: utf-8 -*-? class Animal(object):? ? def run(self):? ? ? ? print('Animal is running...')? class dog(Animal):? pass? if __name__=='__main__':? ? dog().run()

dog 繼承Animal的屬性魔熏,還有類是一個(gè)object衷咽,需要調(diào)run方法鸽扁。

#!/usr/bin/env python3 # -*- coding: utf-8 -*-? class Animal(object):? ? def run(self):? ? ? ? print('Animal is running...')? class dog(Animal):? def dog1(self):? print('dog is ...')? if __name__=='__main__':? ? dog().dog1()

繼承還可以一級(jí)一級(jí)地繼承下來(lái),就好比從爺爺?shù)桨职窒馄⒃俚絻鹤舆@樣的關(guān)系桶现。而任何類,最終都可以追溯到根類object鼎姊,這些繼承關(guān)系看上去就像一顆倒著的樹(shù)骡和。比如如下的繼承樹(shù):

靜態(tài)語(yǔ)言 vs 動(dòng)態(tài)語(yǔ)言:

對(duì)于靜態(tài)語(yǔ)言(例如Java)來(lái)說(shuō),如果需要傳入Animal類型相寇,則傳入的對(duì)象必須是Animal類型或者它的子類慰于,否則,將無(wú)法調(diào)用run()方法唤衫。

對(duì)于Python這樣的動(dòng)態(tài)語(yǔ)言來(lái)說(shuō)婆赠,則不一定需要傳入Animal類型。我們只需要保證傳入的對(duì)象有一個(gè)run()方法就可以了.

小結(jié)

繼承可以把父類的所有功能都直接拿過(guò)來(lái)战授,這樣就不必重零做起页藻,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫(xiě)植兰。

動(dòng)態(tài)語(yǔ)言的鴨子類型特點(diǎn)決定了繼承不像靜態(tài)語(yǔ)言那樣是必須的份帐。

獲取對(duì)象信息:

使用type():

使用isinstance():

使用dir():

對(duì)于class的繼承關(guān)系來(lái)說(shuō),使用type()就很不方便楣导。我們要判斷class的類型废境,可以使用isinstance()函數(shù)。

如果要獲得一個(gè)對(duì)象的所有屬性和方法筒繁,可以使用dir()函數(shù)噩凹,它返回一個(gè)包含字符串的list,比如毡咏,獲得一個(gè)str對(duì)象的所有屬性和方法.

實(shí)例屬性和類屬性:

由于Python是動(dòng)態(tài)語(yǔ)言驮宴,根據(jù)類創(chuàng)建的實(shí)例可以任意綁定屬性。

給實(shí)例綁定屬性的方法是通過(guò)實(shí)例變量呕缭,或者通過(guò)self變量:

#!/usr/bin/env python3 # -*- coding: utf-8 -*-? class Student(object):? ? def __init__(self, name):? ? ? ? self.name = name? s = Student('Bob') s.score = 90? if __name__=='__main__':? s = Student('Bob')? s.score = 90? print(s.score)

小結(jié)

實(shí)例屬性屬于各個(gè)實(shí)例所有堵泽,互不干擾;

類屬性屬于類所有恢总,所有實(shí)例共享一個(gè)屬性迎罗;

不要對(duì)實(shí)例屬性和類屬性使用相同的名字,否則將產(chǎn)生難以發(fā)現(xiàn)的錯(cuò)誤片仿。

七纹安、面向?qū)ο蟾呒?jí)編程

使用__slots__

正常情況下,當(dāng)我們定義了一個(gè)class,創(chuàng)建了一個(gè)class的實(shí)例后厢岂,我們可以給該實(shí)例綁定任何屬性和方法光督,這就是動(dòng)態(tài)語(yǔ)言的靈活性。

正常的情況下可以隨意的添加

為了達(dá)到限制的目的塔粒,Python允許在定義class的時(shí)候可帽,定義一個(gè)特殊的__slots__變量,來(lái)限制該class實(shí)例能添加的屬性:

class Student(object):? ? __slots__ = ('name', 'age') # 用tuple定義允許綁定的屬性名稱

>>> class student(object): ...? ? __slots__ = ('name','age') ... >>> stu = student() >>> stu.name = 'bob' >>> stu.age = 12 >>> stu.score = 12 Traceback (most recent call last):? File "<stdin>", line 1, in <module> AttributeError: 'student' object has no attribute 'score' >>>

由于'score'沒(méi)有被放到__slots__中窗怒,所以不能綁定score屬性映跟,試圖綁定score將得到AttributeError的錯(cuò)誤。

使用__slots__要注意扬虚,__slots__定義的屬性僅對(duì)當(dāng)前類實(shí)例起作用努隙,對(duì)繼承的子類是不起作用的:

class stu2(student): passs s2 = stu2() s2.score = 9999

除非在子類中也定義__slots__,這樣辜昵,子類實(shí)例允許定義的屬性就是自身的__slots__加上父類的__slots__————

新的繼承的不要添加__slots__屬性

使用@property

可以通過(guò)一個(gè)set_score()方法來(lái)設(shè)置成績(jī)荸镊,再通過(guò)一個(gè)get_score()來(lái)獲取成績(jī),這樣堪置,在set_score()方法里躬存,就可以檢查參數(shù):

注意到這個(gè)神奇的@property,我們?cè)趯?duì)實(shí)例屬性操作的時(shí)候舀锨,就知道該屬性很可能不是直接暴露的岭洲,而是通過(guò)getter和setter方法來(lái)實(shí)現(xiàn)的。

@property廣泛應(yīng)用在類的定義中坎匿,可以讓調(diào)用者寫(xiě)出簡(jiǎn)短的代碼盾剩,同時(shí)保證對(duì)參數(shù)進(jìn)行必要的檢查,這樣替蔬,程序運(yùn)行時(shí)就減少了出錯(cuò)的可能性告私。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市承桥,隨后出現(xiàn)的幾起案子驻粟,更是在濱河造成了極大的恐慌,老刑警劉巖凶异,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜀撑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡唠帝,警方通過(guò)查閱死者的電腦和手機(jī)屯掖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門玄柏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)襟衰,“玉大人,你說(shuō)我怎么就攤上這事粪摘∑偕梗” “怎么了绍坝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)苔悦。 經(jīng)常有香客問(wèn)我轩褐,道長(zhǎng),這世上最難降的妖魔是什么玖详? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任把介,我火速辦了婚禮,結(jié)果婚禮上蟋座,老公的妹妹穿的比我還像新娘拗踢。我一直安慰自己,他們只是感情好向臀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布巢墅。 她就那樣靜靜地躺著,像睡著了一般券膀。 火紅的嫁衣襯著肌膚如雪君纫。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天芹彬,我揣著相機(jī)與錄音蓄髓,去河邊找鬼。 笑死舒帮,一個(gè)胖子當(dāng)著我的面吹牛双吆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播会前,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼好乐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了瓦宜?” 一聲冷哼從身側(cè)響起蔚万,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎临庇,沒(méi)想到半個(gè)月后反璃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡假夺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年淮蜈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片已卷。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梧田,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裁眯,我是刑警寧澤鹉梨,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站穿稳,受9級(jí)特大地震影響存皂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逢艘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一旦袋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧它改,春花似錦猜憎、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至爬泥,卻和暖如春柬讨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袍啡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工踩官, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人境输。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓蔗牡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嗅剖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辩越,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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

  • 要點(diǎn): 函數(shù)式編程:注意不是“函數(shù)編程”,多了一個(gè)“式” 模塊:如何使用模塊 面向?qū)ο缶幊蹋好嫦驅(qū)ο蟮母拍钚帕浮傩浴?..
    victorsungo閱讀 1,511評(píng)論 0 6
  • 寫(xiě)在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 2,764評(píng)論 0 8
  • 基礎(chǔ)1.r''表示''內(nèi)部的字符串默認(rèn)不轉(zhuǎn)義2.'''...'''表示多行內(nèi)容3. 布爾值:True黔攒、False(...
    neo已經(jīng)被使用閱讀 1,683評(píng)論 0 5
  • 高階函數(shù):將函數(shù)作為參數(shù) sortted()它還可以接收一個(gè)key函數(shù)來(lái)實(shí)現(xiàn)自定義的排序,reversec參數(shù)可反...
    royal_47a2閱讀 689評(píng)論 0 0
  • pyton review 學(xué)習(xí)指南 https://www.zhihu.com/question/29138020...
    孫小二wuk閱讀 1,050評(píng)論 0 2