Python 把函数视作对象
一等函數(shù)
在 Python 中,函數(shù)是一等對(duì)象。一等對(duì)象需要具備以下幾個(gè)條件:
1.在運(yùn)行時(shí)創(chuàng)建
2.能賦值給變量或者數(shù)據(jù)結(jié)構(gòu)中的元素
3.能作為參數(shù)傳遞給函數(shù)
4.能作為函數(shù)的返回值
在 Python 中,整數(shù)、字符串、字典以及所有的函數(shù)都是一等對(duì)象,接下來(lái)我們來(lái)看把函數(shù)作為對(duì)象的實(shí)際應(yīng)用。
把函數(shù)視作對(duì)象
首先我們通過(guò)一個(gè)簡(jiǎn)單的示例來(lái)說(shuō)明函數(shù)為什么是對(duì)象。
>>> def myFunc(n): ... '''return n!''' ... return n*n ... >>> myFunc(5) 25 >>> myFunc.__doc__ 'return n!' >>> type(myFunc) <class 'function'> >>>首先,我們直接在控制臺(tái)創(chuàng)建一個(gè)函數(shù)。
然后通過(guò)函數(shù)調(diào)用__doc__屬性,而__doc__就是函數(shù)對(duì)象中眾多屬性的其中一個(gè)。
然后通過(guò) type(myFunc)查看函數(shù)類型,它是 function 類的一個(gè)實(shí)例。
由以上示例可以看出函數(shù)其實(shí)就是一個(gè)對(duì)象。
OK,接下來(lái)再通過(guò)一個(gè)示例來(lái)展示函數(shù)對(duì)象的”一等“本性。
>>> fun = myFunc >>> fun <function myFunc at 0x1015a2268> >>> fun(5) 25 >>> map(fun,range(5)) <map object at 0x10177a550> >>> list(map(fun,range(5))) [0, 1, 4, 9, 16] >>>這個(gè)示例中,通過(guò)別的名稱使用函數(shù),再把函數(shù)作為參數(shù)傳遞。
我們把 myFunc函數(shù)賦值給變量 fun,然后通過(guò)變量名來(lái)調(diào)用,還能把它當(dāng)做參數(shù)傳遞給 map 函數(shù),map 函數(shù)返回一個(gè)可迭代的對(duì)象,里面的元素是把第一個(gè)參數(shù)(一個(gè)函數(shù))應(yīng)用到第二個(gè)參數(shù)(一個(gè)可迭代對(duì)象,這里是 range(5))中各個(gè)元素上得到結(jié)果。
有了一等函數(shù),就可以使用函數(shù)式風(fēng)格編程了。函數(shù)式編程的特點(diǎn)之是使用高階函數(shù)。
高階函數(shù)
高階函數(shù)的定義:接收函數(shù)為參數(shù),或者把函數(shù)作為結(jié)果返回的函數(shù)。
比如 map函數(shù)就是一個(gè)高階函數(shù)。另外,內(nèi)置函數(shù) sorted 也是,可選的 key 參數(shù)用于提供一個(gè)函數(shù),它會(huì)應(yīng)用到各個(gè)元素上進(jìn)行排序。
來(lái)看一下 sorted 函數(shù)的簡(jiǎn)單示例:
>>> fruits = ['strawberry','fig','apple','cherry'] >>> sorted(fruits,key = len) ['fig', 'apple', 'cherry', 'strawberry'] >>>任何單參數(shù)函數(shù)都能作為 key 參數(shù)的值。
在看個(gè)示例,為了創(chuàng)建押韻詞典,可以把各個(gè)單詞反過(guò)來(lái)拼寫,然后進(jìn)行排序。
示例:根據(jù)反向拼寫給一個(gè)單詞列表進(jìn)行排序
>>> fruits = ['strawberry','fig','apple','cherry','raspberry'] >>> def reverse(word): ... return word[::-1] ... >>> reverse('testing') 'gnitset' >>> sorted(fruits,key=reverse) ['apple', 'fig', 'raspberry', 'strawberry', 'cherry'] >>>注意,以上示例中列表的單詞并沒(méi)有變,只是把反向拼寫當(dāng)做排序條件。
在函數(shù)式編程中,最熟知的高階函數(shù)有 map、filter、reduce,不過(guò)多數(shù)使用場(chǎng)景下都有更好的替代品。
map、filter與reduce的現(xiàn)代替代品
函數(shù)式編程通常會(huì)提供map、filter與reduce三個(gè)高階函數(shù),在 Python3中,map 和 filter 還是內(nèi)置函數(shù),但是由于引入了列表推導(dǎo)和生成器表達(dá)式,它們變得不那么重要了。可以使用列表推導(dǎo)或生成器表達(dá)式完全具有可以用來(lái)替代這兩個(gè)函數(shù),并且更易于閱讀。
接下來(lái)看看如何用列表式推導(dǎo)來(lái)替代 map 和 filter
>>> list(map(fun,range(6))) [0, 1, 4, 9, 16, 25] >>> [fun(n) for n in range(6)] [0, 1, 4, 9, 16, 25]>>> list(map(fun,filter(lambda n:n%2,range(6)))) [1, 9, 25] >>> [fun(n) for n in range(6) if n%2] [1, 9, 25] >>>Python3中,map 和 filter 返回生成器(一種迭代器),因此現(xiàn)在它們的直接替代品是生成器表達(dá)式。filter 的作用是用于過(guò)濾列表,上面使用量 Lambda 表達(dá)式,其可閱讀性相對(duì)來(lái)說(shuō)沒(méi)有列表推導(dǎo)的高。
接下來(lái)看看 reduce,在 Python2中,reduce 是內(nèi)置函數(shù),但是在 Python3中放到 functools 模塊中了,這個(gè)函數(shù)最常用于求和,但是從 Python2.3起,求和函數(shù)可以使用內(nèi)置的 sum 函數(shù),在可讀性和性能方面,有了很大的改善。
示例:使用 reduce 和sum 計(jì)算和
>>> from functools import reduce >>> from operator import add >>> reduce(add,range(100)) 4950 >>> sum(range(100)) 4950 >>>以上可以看到,使用 reduce 求和需要導(dǎo)入和創(chuàng)建求和函數(shù),但是使用 sum 就不用,非常簡(jiǎn)單。
sum 和 reduce 的通用思想是把某個(gè)操作連續(xù)應(yīng)用到序列的元素上,并累計(jì)之前的結(jié)果,把一系列值歸約成一個(gè)值。
此外,all 和 any 也是內(nèi)置的歸約函數(shù)。
1.all(iterable)
如果iterable的每個(gè)元素都是真值,返回 True,all([])返回 True
2.any(iterable)
如果iterable中有元素是真值,就返回 True,any([])返回 False
本文參考:《流暢的 Python》.
《流暢的 Python》電子書高清中文版下載地址,在這里
總結(jié)
以上是生活随笔為你收集整理的Python 把函数视作对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Qt C++中 Map 和 List
- 下一篇: Qt for Python Mac下使用