本文對Python中的函數(shù)做了一個(gè)系統(tǒng)的總結(jié)。但涉及到的有一些概念并不會(huì)具體展開。
前段時(shí)間我在學(xué)習(xí)閉包,而后又接觸了裝飾器。我在學(xué)習(xí)裝飾器時(shí)經(jīng)常被函數(shù)的嵌套搞的暈頭轉(zhuǎn)向——不都說Python好學(xué),可這裝飾器為啥這么難懂/(ㄒoㄒ)/~~。后來通過了解,我認(rèn)識(shí)到了問題出在函數(shù)身上,對于它的某些特性我還是非常陌生。痛定思痛之后我系統(tǒng)的學(xué)習(xí)了函數(shù),也就有了下面的這篇文章。
plus:如果你還不了解閉包或者裝飾器,那么這篇文章也能為你了解它們做個(gè)鋪墊。
1.第一類對象
說到函數(shù)不得不先引出這個(gè)概念。
維基百科上的定義是這樣的:第一類對象(英語:First-class object)在計(jì)算機(jī)科學(xué)中指可以在執(zhí)行期創(chuàng)造并作為參數(shù)傳遞給其他函數(shù)或存入一個(gè)變數(shù)的實(shí)體。將一個(gè)實(shí)體變?yōu)榈谝活悓ο蟮倪^程叫做“物件化”(Reification)
定義歸定義,看不懂就算了(逃~),下面給出第一類對象的性質(zhì),并分別作介紹(介紹完你就清楚了):
第一類對象
- 可以被存入變量或其他結(jié)構(gòu)
- 可以被作為參數(shù)傳遞給其他函數(shù)
- 可以被作為函數(shù)的返回值
- 可以在執(zhí)行期創(chuàng)造,而無需完全在設(shè)計(jì)期全部寫出
- 即使沒有被系結(jié)至某一名稱,也可以存在
1.1.可以被存入變量或其他結(jié)構(gòu)
Python中的函數(shù)可以被賦值給變量。你可以像使用其他變量一樣使用函數(shù)。
def f1():
pass
a = f1 # 建立了a對函數(shù)f1的一個(gè)引用
a()
被引用的函數(shù)也可以是內(nèi)建函數(shù):
b = abs()
函數(shù)可以被存放于容器之中,在python中這類容器變量有l(wèi)ist,tuple,set,dict。
def f1():
pass
def f2():
pass
a,b = [f1, f2] # 函數(shù)f1,f2存在在列表中,并分別被變量a,b引用
1.2.可以被作為參數(shù)傳遞給其他函數(shù)
def foo(func):
print("Hello")
func()
def func():
print("world")
foo(func)
Hello
world
1.3.可以被作為函數(shù)的返回值
def foo(func):
print("Hello")
return func
def func():
print("world")
foo(func)
Hello
<function __main__.func>
1.4.可以在執(zhí)行期創(chuàng)造,而無需完全在設(shè)計(jì)期全部寫出
def f1():
x = 1
def f2():
print(x)
return f2
a = f1()
a() # 1
# 函數(shù)f1內(nèi)嵌套了函數(shù)f2,當(dāng)執(zhí)行f1時(shí),f2才被定義。
1.5.即使沒有被系結(jié)至某一名稱,也可以存在
最典型的例子莫過于lambda函數(shù)了。
>>>lambda x:x*x
<function __main__.<lambda>>
a = lambda x:x*x
a(2) # 4
2.函數(shù)是第一類對象
你可以發(fā)現(xiàn),上面我舉的例子中都是以函數(shù)作為例子,沒錯(cuò),在Python中,函數(shù)是第一類對象。
如果你接觸過C或其他編程語言,你就會(huì)發(fā)現(xiàn),Python中的函數(shù)擁有這些編程語言所不具有的可作為參數(shù),可作為返回值,可以嵌套等特性。這也解釋了為什么Python能夠支持像裝飾器這樣的強(qiáng)大功能。
知道了這些,你再去了解閉包,裝飾器,相信就會(huì)輕松的多了。