《Fluent Python》讀書筆記-First-Class Functions

概覽

????函數(shù)在python里是作為第一類對象(First Class Objects)囱皿。在編程語言理論里勇婴,定義一個“第一類對象”作為編程對象能夠做到以下幾點(diǎn):

  • 在運(yùn)行時創(chuàng)建
  • 可以賦值給變量或者數(shù)據(jù)結(jié)構(gòu)里的元素
  • 能作為參數(shù)傳遞給函數(shù)
  • 可以作為函數(shù)的返回值

Treating a Function Like an Object

????在python里函數(shù)就是對象,類型是function嘱腥。

>>> def factorial(n):
...     '''returns n!'''
...     return 1 if n < 2 else n * factorial(n-1)
... 
>>> factorial(10)
3628800
>>> factorial.__doc__
'returns n!'
>>> type(factorial)
<class 'function'>
>>> fact = factorial
>>> fact
<function factorial at 0x1053fcf28>
>>> fact(5)
120
>>> map(factorial, range(4))
<map object at 0x10566b160>
>>> list(map(fact, range(4)))
[1, 1, 2, 6]

????上面的例子展示了函數(shù)作為第一類對象的特性耕渴。可以把函數(shù)賦值給一個對象齿兔,并且使用這個對象的名字調(diào)用函數(shù)橱脸。也可以把函數(shù)作為參數(shù)傳遞給另一個函數(shù)础米。

Higher-Order Functions

????一個函數(shù)把函數(shù)作為參數(shù)或者把函數(shù)作為返回結(jié)果就被稱為高階函數(shù)(high-order function)
????函數(shù)式編程通常提供一些通用的高階函數(shù)如map慰技,reduce椭盏,filter等。不過在python里由于list comprehensions還有g(shù)enerator expressions的引入吻商,都不太重要了掏颊。在python3里mapfilter返回生成器,而在python2里返回list艾帐。在python3里reduce被從built-in里移除乌叶,放在了functools模塊里。

Anonymous Functions

????在使用高階函數(shù)時柒爸,有時候創(chuàng)建一個小的准浴,一次性的函數(shù)會很方便,這個就是匿名函數(shù)的由來捎稚。
????匿名函數(shù)是由lambda關(guān)鍵字創(chuàng)建乐横。不過由于匿名函數(shù)句法的局限,匿名函數(shù)的函數(shù)體只能是純表達(dá)式今野。除了作為高階函數(shù)的參數(shù)以為葡公,匿名函數(shù)的使用場景非常有限。

The Seven Flavors of Callable Objects

????call操作符(就是())除了用戶自定義函數(shù)以外条霜,也可以用在其他對象上催什。要確定一個函數(shù)是否是callable的,可以使用內(nèi)建的callable() 函數(shù)宰睡。python定義了七種callable類型:

  • User-defined functions:使用def語句或者用lambda表達(dá)式創(chuàng)建蒲凶。
  • Built-in functions:使用C實現(xiàn)的函數(shù),如len拆内。
  • Built-in methods:使用C實現(xiàn)的方法旋圆,如dict.get。
  • Methods:定義在類里的函數(shù)麸恍。
  • Classes:調(diào)用類就是創(chuàng)建一個實例臂聋。
  • Class instances:類如果定義了__call__方法,那么類的實例也可以像函數(shù)一樣調(diào)用或南。
  • Generator functions:使用yield關(guān)鍵字的函數(shù)或方法孩等。

User-Defined Callable Types

????這一節(jié)介紹的就是7種callabe類型里的第6種。主要使用的場景就是創(chuàng)建在調(diào)用時需要保存內(nèi)部狀態(tài)的像函數(shù)一樣的對象采够,另一種方式就是閉包(Closures)癣防,后面會詳細(xì)講悠就。

From Positional to Keyword-Only Parameters

????python函數(shù)最棒的特性就是極度靈活的參數(shù)處理方式,在python進(jìn)一步增強(qiáng)提供了僅限關(guān)鍵字參數(shù)(keyword-only)岭埠。與之相關(guān)的就是當(dāng)調(diào)用一個函數(shù)時阳柔,使用*去展開iterables和mappings到不同的參數(shù)。

>>>def tag(name, *content, cls=None, **attrs): 
    """Generate one or more HTML tags""" 
    if cls is not None:
        attrs['class'] = cls 
    if attrs:
        attr_str = ''.join(' %s="%s"' % (attr, value) 
                                 for attr, value
                                 in sorted(attrs.items()))
    else:
        attr_str = ''

    if content:
        return '\n'.join('<%s%s>%s</%s>' %
                   (name, attr_str, c, name) for c in content) 
    else:
        return '<%s%s />' % (name, attr_str)
>>> tag('br')
'<br />'
>>> tag('p', 'hello')
'<p>hello</p>'
>>> print(tag('p', 'hello', 'world'))
<p>hello</p>
<p>world</p>
>>> tag('p', 'hello', id=33)
'<p id="33">hello</p>'
>>> print(tag('p', 'hello', 'world', cls='sidebar'))
<p class="sidebar">hello</p>
<p class="sidebar">world</p>
>>> tag(content='testing', name="img")
'<img content="testing" />'
>>> my_tag = {'name': 'img', 'title': 'Sunset Boulevard',
... 'src': 'sunset.jpg', 'cls': 'framed'}
>>> tag(**my_tag)
'<img class="framed" src="sunset.jpg" title="Sunset Boulevard" />'

????僅限關(guān)鍵字參數(shù)(keyword-only)是python3里的新特性。參數(shù)只能作為關(guān)鍵字參數(shù),而不能從未命名的位置參數(shù)捕獲蝴罪。要定義一個僅限關(guān)鍵字參數(shù),就把他放在前綴的參數(shù)后面步清。如果不需要變化的參數(shù)要门,但是還需要僅限關(guān)鍵字參數(shù),那么就直接放在的后面廓啊。

Retrieving Information About Parameters

????函數(shù)對象有幾個內(nèi)省的屬性存儲了參數(shù)信息:

  • __defaults__:存儲了參數(shù)的默認(rèn)值
  • __kwdefaults__:存儲了keyword-only參數(shù)的默認(rèn)值
  • __code____code__.co_varnames存儲了參數(shù)名和局部變量的名字欢搜,通過__code__.co_argcount定位前N個作為參數(shù)。
    ????更簡單的是使用inspect.signature來獲取參數(shù)信息谴轮。

Function Annotations

????python3提供了語法給函數(shù)的參數(shù)和返回值附加一些元數(shù)據(jù)炒瘟。如類型還有限制條件,不過現(xiàn)在python只是做了些記錄第步,并沒有去做檢查疮装。

Packages for Functional Programming

????operator包里包含了很多算術(shù)操作符,另外幾個比較有用的函數(shù)itemgetter粘都,attrgetter斩个,methodcaller
????functools包里主要介紹了partial驯杜,可以用來生成一個新的callable其中的一些參數(shù)值固定。

>>> a = range(10)
>>> from operator import itemgetter
>>> a_itemgetter = itemgetter(5, 1)
>>> a_itemgetter(a)
(5, 1)
>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long')
>>> latlon = LatLong(30, 140)
>>> from operator import attrgetter
>>> attr_lat = attrgetter('lat')
>>> attr_lat(latlon)
30
>>> from operator import methodcaller
>>> s = 'The time has come'
>>> upcase = methodcaller('upper')
>>> upcase(s)
'THE TIME HAS COME'
>>> from operator import mul
>>> from functools import partial
>>> triple = partial(mul, 3)
>>> triple(7)
21
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末做个,一起剝皮案震驚了整個濱河市鸽心,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌居暖,老刑警劉巖顽频,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異太闺,居然都是意外死亡糯景,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門省骂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟀淮,“玉大人,你說我怎么就攤上這事钞澳〉』蹋” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵轧粟,是天一觀的道長策治。 經(jīng)常有香客問我脓魏,道長,這世上最難降的妖魔是什么通惫? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任茂翔,我火速辦了婚禮,結(jié)果婚禮上履腋,老公的妹妹穿的比我還像新娘珊燎。我一直安慰自己,他們只是感情好府树,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布俐末。 她就那樣靜靜地躺著,像睡著了一般奄侠。 火紅的嫁衣襯著肌膚如雪卓箫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天垄潮,我揣著相機(jī)與錄音烹卒,去河邊找鬼。 笑死弯洗,一個胖子當(dāng)著我的面吹牛旅急,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牡整,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼藐吮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逃贝?” 一聲冷哼從身側(cè)響起谣辞,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沐扳,沒想到半個月后泥从,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沪摄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年躯嫉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杨拐。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡祈餐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哄陶,到底是詐尸還是另有隱情昼弟,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布奕筐,位于F島的核電站舱痘,受9級特大地震影響变骡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芭逝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一塌碌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旬盯,春花似錦台妆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萨咳,卻和暖如春懊缺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背培他。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工鹃两, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舀凛。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓俊扳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猛遍。 傳聞我的和親對象是個殘疾皇子馋记,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

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