採用書籍Python核心編程(第二版),人民郵電出版社,2008年7月第1版。本書以Python2.5爲主,但筆記主要以Python3.6爲主。
第11章 函數和函數式編程
11.1 函數
- 函數是對程序邏輯進行結構化或過程化的一種編程方法,易於管理
- 一般來說,過程和函數類似。過程是沒有返回值的,函數有返回值。但是,在Python中,過程就是函數,因爲解釋器會隱式地返回None
# 1.隱式返回None
def hello():
print('hello')
res = hello()
print(res) # None
# 2.可以返回一個值或對象
def foo():
return 123
def foo():
return (123, 'ben') # 等價於return 123,'ben'
# 3.許多靜態類型的語言主張一個函數的類型就是其返回值的類型,而Python是動態地確定類型而且函數能返回不同類型的值。
11.2 調用函數
- 函數操作符:小括號()。函數名後跟着()表示調用,表示該函數是可調用的或可執行的。Python中一切皆對象,函數名也是對象;如果一個對象後可以加上小括號執行,表示該對象是可執行的(callable)
- 位置參數:普通形式的參數,沒有默認值。調用時可以按參數順序傳入數據,也可以按關鍵字形式傳入(x=123,按關鍵字傳入可以不按順序)。如果混合使用,需把關鍵字參數至於最後
- 默認參數:聲明瞭默認值的參數,調用時可以不傳入參數
- 可變參數、關鍵字參數和命名關鍵字參數。Python教程 - 函數的參數 - 廖雪峯的官方網站
11.3 創建函數
- 創建函數:def function_name(args): …
- Python中函數聲明和定義視爲一體。變量聲明和定義也是一體。
- 和其他高級語言類似,Python不允許在函數未聲明之前,對其進行引用和調用。
- 函數擁有屬性,用句點屬性(.)表示進行訪問。可以把函數看作一個命名空間(namespace),在該空間裏包含了函數的屬性。
- 內部函數。除非對內部函數有外部引用,否則只能在外部函數內進行調用
- 裝飾器:Python裝飾器
def function_name(arguments):
'''function doc'''
pass
def foo():
'''foo function''' # 隱式地在函數命名空間操作
__doc__ = '''foo function''' # 這不是在函數命名空間操作,而是在函數內定義了一個臨時變量
foo.__version__ = '1.0' # 顯式地在函數命名空間操作,定義了一個版本變量
print(foo.__doc__)
print(foo.__version__)
11.4 傳遞函數
- 函數也是對象,可以被引用,通過引用來傳遞
- 函數對象的引用——foo,函數對象的調用——foo()
def foo():
print('foo')
print(foo) # 打印foo引用的函數對象
foo() # 調用foo引用的函數
bar = foo # 通過賦值引用相同的函數對象
bar()
11.5 函數參數
Python函數參數
Python教程 - 函數的參數 - 廖雪峯的官方網站
11.6 函數式編程
- 匿名函數與lambda:創建匿名函數lambda args: expression
- 內建函數:過濾函數filter()、映射函數map()、疊加計算函數reduce()
- 偏函數:把其他函數的部分參數默認化,便於使用
myadd = lambda x,y: x+y
print(myadd)
res = myadd(1, 2)
print(res)
def odd(n):
return n % 2
res = list(filter(odd, list(range(10))))
print(res)
res = list(map(lambda x: x**2, [0, 1, 2, 3, 4, 5]))
print(res)
res = list(map(lambda x,y: x+y, [1,3,5], [2,4,6]))
print(res)
from functools import reduce
l1=[0, 1, 2, 3, 4, 5, 6]
def add(x,y):
return x + y
print(reduce(add, l1))
from functools import partial
from operator import add
add1 = partial(add, 1)
add1(10)
add1(100)
11.7 變量作用域
- 標識符的作用域定義爲其聲明在程序裏的可應用範圍,也就是我們所說的變量可見性
- 全局變量與局部變量:當搜索一個變量名的時候,Python解釋器先從局部作用域開始搜索;如果在局部作用域內沒有找到改變量名,就會在全局域搜索這個變量名;如果在全局域也找不到則拋出 NameError 異常。
- global語句:如果將全局變量在一個函數內聲明,那麼全局變量會被局部變量給覆蓋。由於Python動態性,要在局部明確引用一個已命名的全局變量,必須使用global var1, var2, …
- 閉包(closure):如果在一個內部函數裏,對外部作用域(但不是全局作用域)的變量進行引用,那麼內部函數就被認爲是閉包。
11.8 生成器
暫略。