第五章 一等函數
把函數視作對象
Python即可以函數式編程,也可以面向對象編程,
所以我們應該清楚的明白,
函數在本質上和字典列表之類的並沒有區別
下面通過一個小例子來展示函數的『一等性』
def factorial(n):n n return nn n return 1 if n < 2 else n * factorial(n-1)nnprint(factorial.__doc__)nprint(type(factorial))nprint(factorial(3))nnnOUTnn return nnn<class function>n6nn
高階函數
接受函數作為參數,或者把函數作為返回結果的函數就是高階函數。類似的高階函數有:map,filter,reduce等
以sorted為例,展示一下高階函數的使用:
fruits = [strawberry,apple,cherry,banana]nn# 展示高階函數sorted的使用nprint (sorted(fruits,key=len))nnnOUT:nn[apple, cherry, banana, strawberry]nn
Python3 中map、filter、reduce的替代品
在Python3中,提供了更加高級和易用的特性:列表推導式和生成器表達式
fact = factorialnnprint(list(map(fact, range(6))))nnprint([fact(n) for n in range(6)])nnnOUT:n[1, 1, 2, 6, 24, 120]n[1, 1, 2, 6, 24, 120]nn
自定義可調用類型
不僅函數是真正的對象,對象也都可以表現的想函數一樣:可被調用
這需要我們實現類的__call__方法
import randomnnnclass BingoCage:nn def __init__(self, items):n self._items = list(items)n random.shuffle(self._items)nn def pick(self):n try:n return self._items.pop()n except IndexError:n raise LookupError(pick form empty BingoCage)nn def __call__(self):n return self.pick()nnnbingo = BingoCage(range(3))nnprint(bingo.pick())nprint(bingo())nnnOUT:n1n2nn
函數的參數
Python最好的特性之一是提供了極為靈活的參數處理機制,
下面我們來展示如何使用這些特性def tag(name, *content, cls=None, **attrs):n 生成一個或者多個html標籤nn if cls is not None:n attrs[class] = clsn if attrs:n attr_str = .join( {}="{}" .format(attr, value)n for attr, value in sorted(attrs.items()))n else:n attr_str = nn if content:n return n.join(<{}{}>{}</{}>.format(name, attr_str, c, name) for c in content)n else:n return <{}{} />.format(name, attr_str)nnn# 傳入單個定位參數,生成一個指定名稱的空標籤nprint(tag(br))n# 第一個參數後面的任意個參數會被*content捕獲,存入一個元組nprint(tag(p, hello,world))n# 沒有指定明確官架子的參數會給**attrs捕獲,存入一個字典nprint(tag(p, hello,world, id=333))nmy_tag = {name: img, little: sunset boulevard,n src: sunset.jpg, cls: framed}n# 在my_tag前加入** 滋滋暗中的所有元素作為單個參數傳入,同鍵名會綁定到對應的具名參數上,餘下的會被**attrs捕獲nprint(tag(**my_tag))nnnOUT:nn<br />n<p>hello,world</p>n<p id="333" >hello,world</p>n<img class="framed" little="sunset boulevard" src="sunset.jpg" />nn
第五章小結
其實高階函數已經不那麼重要了!
本章的目標是探討函數的一本性,這意味著我們可以將函數值賦給變數、傳給其他函數、存儲在數據結構中、以及訪問函數的屬性。
函數作為編程思想力非常重要的一個部分,我們得靈活的掌握他的用法,對於參數的靈活的調用也是必不可少的。
關於匿名函數(lambad)我並沒有將內容寫入筆記,因為我並不能很好的理解lambda的意義(難道僅僅是為了好看?語法糖?)
關於匿名函數有這樣一段說法:
Lundh 提出的 lambda 表達式重構秘笈如果使用 lambda 表達式導致一段代碼難以理解,Fredrik Lundh 建議像下面這樣重構。
(1) 編寫注釋,說明 lambda 表達式的作用。(2) 研究一會兒注釋,並找出一個名稱來概括注釋。
(3) 把 lambda 表達式轉換成 def 語句,使用那個名稱來定義函數。(4) 刪除注釋。摘自「Functional Programming HOWTO」
每天的學習記錄都會 同步更新到:
微信公眾號: findyourownway
知乎專欄:https://zhuanlan.zhihu.com/zen-of-pythonBlog : www.ehcoblog.mlGithub: https://github.com/Ehco1996/推薦閱讀:
※Python中Turtle模塊的基本指令都有哪些?
※已經有了各省的數據,如何將信息以可視化的方式顯示在地圖上?順便問一下python有相關的第三方包沒?
※極光日報 第 163 期 | 2017 / 4 / 24
※pyinstaller無法打包含requests模塊的程序?
TAG:Python |