流畅的python学习记录——第五章:一等函数
- 流暢的python學習記錄——第一章:python數據模型
- 流暢的python學習記錄——第二章:數據結構——序列構成的數組
- 流暢的python學習記錄——第三章:字典和集合
- 流暢的python學習記錄——第四章:None
- 流暢的python學習記錄——第五章:一等函數
- 流暢的python學習記錄——第六章:None
- 流暢的python學習記錄——第七章:函數裝飾器和閉包
- 流暢的python學習記錄——第八章:None
5.1 簡介
- “把函數視作一等對象”簡稱為“一等函數”。
- “一等對象”定義為滿足下述條件的程序實體:
- 在運行時創建
- 能賦值給變量或數據結構中的元素
- 能作為參數傳給函數
- 能作為函數的返回結果
5.2 函數為一等對象
下面的例子證明函數是“一等對象”。
- 可以把 factorial 函數賦值給變量 fact, 然后通過變量名調用。
- 可以作為參數傳給map 函數。
5.3 高階函數
**接受函數為參數, 或者把函數作為結果返回的函數是高階函數(higherorder function)。**下面的幾個函數都屬于高階函數:
- map 函數
- 內置函數 sorted
- filter函數
- reduce函數
5.3.1 map函數
根據提供的函數對指定序列做映射, 并返回映射后的序列,定義:
map(func, *iterables) --> map object
- function # 序列中的每個元素需要執行的操作, 可以是匿名函數
- iterables # 一個或多個序列
5.3.2 sorted 函數
sorted 函數默認將序列升序排列后返回一個新的 list,還可以自定義鍵函數來進行排序,也可以設置 reverse 參數確定是升序還是降序。函數定義如下:
sorted(iterable, cmp=None, key=None, reverse=False)
- iterable # 序列
- key # 可以用來計算的排序函數
- reverse # 排序規則,reverse = True 降序,reverse = False 升序(默認)
5.3.3 filter函數
filter() 函數用來過濾序列中不符合條件的值,返回一個迭代器,該迭代器生成那些函數(項)為 true 的 iterable 項。如果函數為 None,則返回為 true 的項。定義如下:
- filter(function or None, iterable)
- function or None # 過濾操作執行的函數
- iterable # 需要過濾的序列
5.3.4 reduce函數
reduce 函數需要傳入一個有兩個參數的函數,然后用這個函數從左至右順序遍歷序列并生成結果,定義如下:
reduce(function, sequence[, initial])
from functools import reduceresult = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]) print(result)# 設定初始參數: s = reduce(lambda x, y: x + y, ['1', '2', '3', '4', '5'], "數字 = ") print(s) 15 數字 = 123455.4 匿名函數(lambda 關鍵字)
在參數列表中最適合使用匿名函數。
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana'] print(sorted(fruits, key=lambda word: word[::-1])) ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']5.5 可調用對象
可調用對象,即任何可以通過函數操作符()來調用的對象。
python可調用對象大致可以分為4類:
- 函數:內建函數(BIFs)、用戶自定義函數(UDF)、lambda表達式
- 方法:和函數類似,方法也有內建方法(BIM)和用戶自定義方法(UDM)。用戶自定義方法是在類的定義體中定義的函數;內建方法,如一個python數據類型如列表和字典,如dict.get。內建方法和內建函數不同之處在于,內建方法的__self__屬性指向一個python對象,而內建函數的__self__指向None
- 類: 調用類時會運行類的 __new__ 方法創建一個實例, 然后運行__init__ 方法, 初始化實例, 最后把實例返回給調用方。
- 某些類的實例:__call__方法允許程序員創建可調用的對象(實例)。默認情況下,call()是沒有實現的,即大多數的類的實例是不可調用的。而如果類中實現了__call__這個方法,那么這個類的實例就成了可調用的了。
Python 中有各種各樣可調用的類型, 因此判斷對象能否調用, 最安全的方法是使用內置的 callable() 函數。
print(abs, str, 13) [callable(obj) for obj in (abs, str, 13)] <built-in function abs> <class 'str'> 13[True, True, False]5.6 用戶定義的可調用類型
只需實現實例方法 __call__, 任何 Python 對象都可以表現得像函數。
import random class BingoCage:def __init__(self, items):self._items = list(items)def pick(self):try:return self._items.pop()except IndexError:raise LookupError('pick from empty BingoCage')def __call__(self):return self.pick()bingo1 = BingoCage(range(3)) print(bingo1.pick())bingo2 = BingoCage(range(3)) print(bingo2()) 2 25.7 函數內省
- 在計算機編程中,自省是指這種能力:檢查某些事物以確定它是什么、它知道什么以及它能做什么。自省向程序員提供了極大的靈活性和控制力。
- 自省就是面向對象的語言所寫的程序在運行時,能夠知道對象的類型。簡單一句就是,運行時能夠獲知對象的類型。
5.8 位置參數、默認參數、關鍵字參數、可變參數區別
5.8.1 位置參數-默認參數
- 位置參數:調用函數時根據函數定義的參數位置來傳遞參數。
- 默認參數:為參數提供默認值,調用函數時可傳可不傳該默認參數的值。
5.8.2 可變參數
- 函數定義的時候,在參數前面加一個*,那么這個參數是可變參數。
- 調用函數的時候,可變參數可以接收0個或者任意個實參,并自動組裝成元組。元組中的元素就是傳入的實參。
- 當已經有了序列,一些數據的集合,調用函數時,可以用星號將序列中的元素取出,傳給形參
5.8.3 關鍵字參數
- 函數定義的時候,參數前面加**,這個參數是關鍵字參數。
- 關鍵字參數接收的是含有參數名的參數(比如a=1),將接收的參數組裝成一個字典給關鍵字參數。
- 如果已經有了一個字典,想要使用字典中的元素,可以用**取出字典中的元素傳給關鍵字參數。
- 傳入帶有參數名的參數,要注意參數名的使用,參數名傳入關鍵參數會轉化成字符串,參數名不能為字符串。
5.9 函數注解
- 用于為函數聲明中的參數和返回值附加元數據。
- 函數聲明中的各個參數可以在 : 之后增加注解表達式。
- 如果參數有默認值, 注解放在參數名和 = 號之間。
- 如果想注解返回值, 在 ) 和函數聲明末尾的 : 之間添加 -> 和一個表達式。 那個表達式可以是任何類型。
- 注解不會做任何處理, 只是存儲在函數的 __annotations__ 屬性(一個字典) 中
5.10 函數式編程
函數式編程是一種編程范式,不同于之前的面向對象編程。它是面向數學的抽象,也就是說,這里的函數二字不再是我們編程語言中的函數,而是數學中的函數了。
這一個小結先不做詳細理解,具體可以參考: https://glumes.com/post/python/python-functional-programming/
總結
以上是生活随笔為你收集整理的流畅的python学习记录——第五章:一等函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10 + 独显 + Anacond
- 下一篇: 《简明python教程》沈洁元