fluent python- 第 5 章 一等函數-面向對象(附第四章-文本和字節(jié)序列)

第 4 章 文本和字節(jié)序列

人類使用文本林说, 計算機使用字節(jié)序列。


第 5 章 一等函數

前言:

在 Python 中屯伞, 函數是一等對象腿箩。 編程語言理論家把“一等對象”定義為滿足下述條件的程序實體:
1、在運行時創(chuàng)建
2劣摇、能賦值給變量或數據結構中的元素
3珠移、能作為參數傳給函數
4、能作為函數的返回結果


5.1 把函數視作對象

map、 filter和reduce的現(xiàn)代替代品
函數式語言通常會提供 map剑梳、 filter 和 reduce 三個高階函數( 有時使用不同的名稱) 唆貌。 在 Python 3 中, map 和 filter 還是內置函數垢乙, 但是由于引入了列表推導和生成器表達式锨咙, 它們變得沒那么重要了。 列表推導或生成器表達式具有 map 和 filter 兩個函數的功能追逮, 而且更易于閱讀酪刀, 如示例:

>>> list(map(fact, range(6))) ?   # fact是一個提前定義好的階乘函數n!
[1, 1, 2, 6, 24, 120]
>>> [fact(n) for n in range(6)] ?
[1, 1, 2, 6, 24, 120]
>>> list(map(factorial, filter(lambda n: n % 2, range(6)))) ?
[1, 6, 120]
>>> [factorial(n) for n in range(6) if n % 2] ?
[1, 6, 120]
>>>


5.3 匿名函數

Python 簡單的句法限制了 lambda 函數的定義體只能使用純表達
式。 換句話說钮孵, lambda 函數的定義體中不能賦值骂倘, 也不能使用 while
和 try 等 Python 語句,在參數列表中最適合使用匿名函數。

>>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
>>> sorted(fruits, key=lambda word: word[::-1])
['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']

除了作為參數傳給高階函數之外巴席, Python 很少使用匿名函數历涝。 由于句法上的限制, 非平凡的 lambda 表達式要么難以閱讀漾唉, 要么無法寫出.


5.4 可調用對象

除了用戶定義的函數荧库, 調用運算符( 即 ()) 還可以應用到其他對象
上。 如果想判斷對象能否調用赵刑, 可以使用內置的 callable() 函數分衫。
Python 數據模型文檔列出了 7 種可調用對象:

  1. 用戶定義的函數:使用 def 語句或 lambda 表達式創(chuàng)建。
  2. 內置函數
  3. 內置方法
  4. 方法
  5. 類的實例
  6. 生成器函數

5.5 用戶定義的可調用類型

不僅 Python 函數是真正的對象般此, 任何 Python 對象都可以表現(xiàn)得像函
數蚪战。 為此, 只需實現(xiàn)實例方法 __call__铐懊。

import random
class BingoCage:
    def __init__(self, items):
        self._items = list(items)
        random.shuffle(self._items)   # 隨機洗牌
    def pick(self):
        try:  # list = [1,2,3]; list.pop()結果為3邀桑,再輸入list,結果為[1,2]
            return self._items.pop()
        except ImportError:
            raise LookupError('pick from empty BigoCate')
    def __call__(self):
        return self.pick()  # 實現(xiàn)bingo.pick() 的快捷方式是 bingo()

bingo = BingoCage(range(3))
print( bingo.pick() )   # 結果:0 or 1 or 2
print( bingo() )   # 上方已經定義了隨機洗牌 ; ??bingo已經是實例,我們還可以 實例(),表現(xiàn)的像函數 
print( callable(bingo) )  # True


5.6 函數內省

除了__doc__科乎, 函數對象還有很多屬性概漱。 使用 dir 函數可以探知
factorial(已定義的一個函數) 具有下述屬性:

>>> dir(factorial)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__',
'__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__',
'__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__']
>>>

列出常規(guī)對象沒有而函數有的屬性

>>> class C: pass # ?
>>> obj = C() # ?
>>> def func(): pass # ?
>>> sorted(set(dir(func)) - set(dir(obj))) # ?
['__annotations__', '__call__', '__closure__', '__code__', '__defaults__',
'__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__']
>>>

? 創(chuàng)建一個空的用戶定義的類。
? 創(chuàng)建一個實例喜喂。
? 創(chuàng)建一個空函數瓤摧。
? 計算差集, 然后排序玉吁, 得到類的實例沒有而函數有的屬性列表照弥。


5.7 從定位參數到僅限關鍵字參數

*args 參數會被存入一個元組
**kwargs 參數會被存入一個字典


5.11 本章小結

本章的目標是探討 Python 函數的一等本性。 這意味著进副, 我們可以把函數賦值給變量这揣、 傳給其他函數悔常、 存儲在數據結構中, 以及訪問函數的屬性给赞, 供框架和一些工具使用机打。 高階函數是函數式編程的重要組成部分,即使現(xiàn)在不像以前那樣經常使用 map片迅、 filter 和 reduce 函數了残邀, 但是還有列表推導( 以及類似的結構, 如生成器表達式) 以及 sum柑蛇、 all和 any 等內置的歸約函數芥挣。 Python 中常用的高階函數有內置函數sortedmin耻台、 maxfunctools. partial空免。

Python 有 7 種可調用對象, 從 lambda 表達式創(chuàng)建的簡單函數到實現(xiàn)__call__ 方法的類實例盆耽。 這些可調用對象都能通過內置的callable() 函數檢測蹋砚。 每一種可調用對象都支持使用相同的豐富句法聲明形式參數, 包括僅限關鍵字參數和注解——二者都是 Python 3 引入的新特性摄杂。

Python 函數及其注解有豐富的屬性坝咐, 在 inspect 模塊的幫助下, 可以讀取它們匙姜。 例如畅厢, Signature.bind 方法使用靈活的規(guī)則把實參綁定到形參上冯痢, 這與 Python 使用的規(guī)則一樣氮昧。

最后, 本章介紹了 operator 模塊中的一些函數浦楣, 以及
functools.partial 函數袖肥, 有了這些函數, 函數式編程就不太需要功
能有限的 lambda 表達式了振劳。


雜談

Python 是函數式語言嗎椎组?

編程語言“范式”已近末日, 它們是舊時代的遺留物历恐, 令人厭煩寸癌。 既然現(xiàn)代語言的設計者對范式不屑一顧, 那么我們的課程為什么要像奴隸一樣對其言聽計從弱贼?

在那篇論文中蒸苇, 下面這一段點名提到了 Python:
對 Python、 Ruby 或 Perl 這些語言還要了解什么呢吮旅? 它們的設
計者沒有耐心去精確實現(xiàn)林奈層次結構溪烤; 設計者按照自己的意
愿從別處借鑒特性, 創(chuàng)建出完全無視過往概念的大雜燴。
Krishnamurthi 指出檬嘀, 不要試圖把語言歸為某一類槽驶; 相反, 把它們視
作特性的聚合更有用鸳兽。
為 Python 提供一等函數打開了函數式編程的大門掂铐, 不過這并不是
Guido 的目的。 他在“Origins of Python's Functional Features”一文
http://python-history.blogspot.com/2009/04/origins-of-pythonsfunctional-features.html) 中說贸铜, map堡纬、 filter 和 reduce 的最初目的是為 Python 增加 lambda 表達式。 這些特性都由 Amrit Prem 貢獻蒿秦, 添加在 1994 年發(fā)布的 Python 1.0 中( 參見 CPython 源碼中的
Misc/HISTORY 文件烤镐,https://hg.python.org/cpython/file/default/Misc/HISTORY) 。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末棍鳖,一起剝皮案震驚了整個濱河市炮叶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渡处,老刑警劉巖镜悉,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異医瘫,居然都是意外死亡侣肄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門醇份,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稼锅,“玉大人,你說我怎么就攤上這事僚纷【鼐啵” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵怖竭,是天一觀的道長锥债。 經常有香客問我,道長痊臭,這世上最難降的妖魔是什么哮肚? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮广匙,結果婚禮上允趟,老公的妹妹穿的比我還像新娘。我一直安慰自己艇潭,他們只是感情好拼窥,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布戏蔑。 她就那樣靜靜地躺著,像睡著了一般鲁纠。 火紅的嫁衣襯著肌膚如雪总棵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天改含,我揣著相機與錄音情龄,去河邊找鬼。 笑死捍壤,一個胖子當著我的面吹牛骤视,可吹牛的內容都是我干的。 我是一名探鬼主播鹃觉,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼专酗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盗扇?” 一聲冷哼從身側響起祷肯,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疗隶,沒想到半個月后佑笋,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡斑鼻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年蒋纬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坚弱。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜀备,死狀恐怖,靈堂內的尸體忽然破棺而出史汗,到底是詐尸還是另有隱情琼掠,我是刑警寧澤拒垃,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布停撞,位于F島的核電站,受9級特大地震影響悼瓮,放射性物質發(fā)生泄漏戈毒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一横堡、第九天 我趴在偏房一處隱蔽的房頂上張望埋市。 院中可真熱鬧,春花似錦命贴、人聲如沸道宅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽污茵。三九已至樱报,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泞当,已是汗流浹背迹蛤。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留襟士,地道東北人盗飒。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓赤拒,卻偏偏與公主長得像帘不,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吓妆,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容

  • http://python.jobbole.com/85231/ 關于專業(yè)技能寫完項目接著寫寫一名3年工作經驗的J...
    燕京博士閱讀 7,557評論 1 118
  • 前言 人生苦多嗜历,快來 Kotlin 汗贫,快速學習Kotlin! 什么是Kotlin秸脱? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,163評論 9 118
  • 原文鏈接:https://github.com/EasyKotlin 值就是函數落包,函數就是值。所有函數都消費函數摊唇,...
    JackChen1024閱讀 5,957評論 1 17
  • Python進階框架 希望大家喜歡咐蝇,點贊哦首先感謝廖雪峰老師對于該課程的講解 一、函數式編程 1.1 函數式編程簡...
    Gaolex閱讀 5,493評論 6 53
  • 本文翻譯自Functional Programming Howto 本文將介紹Python中函數式編程的特性巷查。在對...
    大蟒傳奇閱讀 2,603評論 4 14