函數作為第一類對象(First-Class Object)卻是 Python 函數的一大特性。那究竟什么是第一類對象呢?
雙江網站建設公司成都創(chuàng)新互聯公司,雙江網站設計制作,有大型網站制作公司豐富經驗。已為雙江1000+提供企業(yè)網站建設服務。企業(yè)網站搭建\外貿網站建設要多少錢,請找那個售后服務好的雙江做網站的公司定做!
在 Python 中萬物皆為對象,函數也不例外,函數作為對象可以賦值給一個變量、可以作為元素添加到集合對象中、可作為參數值傳遞給其它函數,還可以當做函數的返回值,這些特性就是第一類對象所特有的。
正確理解 Python函數,能夠幫助我們更好地理解 Python 裝飾器、匿名函數(lambda)、函數式編程等高階技術。先來看一個簡單的例子
def foo(text):
... return len(text)
...
foo("zen of python")
13
這是一個再簡單不過的函數,用于計算參數 text 的長度,調用函數就是函數名后面跟一個括號,再附帶一個參數,返回值是一個整數。
函數是對象
函數身為一個對象,擁有對象模型的三個通用屬性:id、類型、和值。
id(foo)
4361313816
type(foo)
class 'function'
foo
function foo at 0x103f45e18
作為對象,函數可以賦值給一個變量
bar = foo
賦值給另外一個變量時,函數并不會被調用,僅僅是在函數對象上綁定一個新的名字而已。
bar("zen of python")
13
同理,你還可以把該函數賦值給更多的變量,唯一變化的是該函數對象的引用計數不斷地增加,本質上這些變量最終指向的都是同一個函數對象。
a = foo
函數可以存儲在容器
容器對象(list、dict、set等)中可以存放任何對象,包括整數、字符串,函數也可以作存放到容器對象中,例如
funcs = [foo, str, len]
foo 是我們自定義的函數,str 和 len 是兩個內置函數。for 循環(huán)逐個地迭代出列表中的每個元素時,函數對象賦值給了 f 變量,調用 f(“hello”) 與 調用 foo(“hello”) 本質是一樣的效果,每次 f 都重新指向一個新的函數對象。當然,你也可以使用列表的索引定位到元素來調用函數。
funcs[0]("Python之禪")
# 等效于 foo("Python之禪")
8
函數可以作為參數
函數還可以作為參數值傳遞給另外一個函數,例如:
def show(func):
... size = func("python 之禪") # 等效于 foo("Python之禪")
... print ("length of string is : %s" % size)
...
show(foo)
length of string is : 9
函數可以作為返回值
函數作為另外一個函數的返回值,例如:
def nick():
還可以簡寫為
nick()("python")
函數接受一個或多個函數作為輸入或者函數輸出(返回)的值是函數時,我們稱這樣的函數為高階函數,比如上面的 show 和 nick 都屬于高階函數。
Python內置函數中,典型的高階函數是 map 函數,map 接受一個函數和一個迭代對象作為參數,調用 map 時,依次迭代把迭代對象的元素作為參數調用該函數。
map(foo, ["the","zen","of","python"])
lens = map(foo, ["the","zen","of","python"])
list(lens)
[3, 3, 2, 6]
map 函數的作用相當于:
[foo(i) for i in ["the","zen","of","python"]]
[3, 3, 2, 6]
只不過 map 的運行效率更快一點。
函數可以嵌套
Python還允許函數中定義函數,這種函數叫嵌套函數。
def get_length(text):
... def clean(t): # 2
... return t[1:]
... new_text = clean(text) # 1
... return len(new_text)
...
get_length("python")
5
這個函數的目的是去除字符串的第一個字符后再計算它的長度,盡管函數本身的意義不大,但能足夠說明嵌套函數。get_length 調用時,先執(zhí)行1處代碼,發(fā)現有調用 clean 函數,于是接著執(zhí)行2中的代碼,把返回值賦值給了 new_text ,再繼續(xù)執(zhí)行后續(xù)代碼。
clean("python")
Traceback (most recent call last):
File "stdin", line 1, in module
NameError: name 'clean' is not defined
函數中里面嵌套的函數不能在函數外面訪問,只能是在函數內部使用,超出了外部函數的做用域就無效了。
實現了 __call__ 的類也可以作為函數
對于一個自定義的類,如果實現了 __call__ 方法,那么該類的實例對象的行為就是一個函數,是一個可以被調用(callable)的對象。例如:
class Add:
def __init__(self, n):
self.n = n
def __call__(self, x):
return self.n + x
add = Add(1)
add(4)
5
執(zhí)行 add(4) 相當于調用 Add.__call__(add, 4),self 就是實例對象 add,self.n 等于 1,所以返回值為 1+4
add(4)
確定對象是否為可調用對象可以用內置函數callable來判斷。
callable(foo)
True
callable(1)
False
callable(int)
True
總結
Python中包含函數在內的一切皆為對象,函數作為第一類對象,支持賦值給變量,作為參數傳遞給其它函數,作為其它函數的返回值,支持函數的嵌套,實現了__call__方法的類實例對象也可以當做函數被調用。
定義:
def 函數名(形參1,形參2='初始定義的內容'):
函數中執(zhí)行的內容
調用:
函數名(實參1)或函數名(形參2=實參2,形參1=實參1)或函數名(實參1,實參2)
例如上面的例子,實現一個整形集合的累加。假設lst = [1,2,3,4,5],實現累加的方式有很多:
第一種:用sum函數。
sum(lst)
第二種:循環(huán)方式。
def customer_sum(lst):
result = 0
for x in lst:
result+=x
return result
def customer_sum(lst):
result = 0
while lst:
temp = lst.pop(0)
result+=temp
return result
if name ==" main ":
lst = [1,2,3,4,5]
print customer_sum(lst)
第三種:遞推求和
def add(lst,result):
if lst:
temp = lst.pop(0)
temp+=result
return add(lst,temp)
else:
return result
if name ==" main ":
lst = [1,2,3,4,5]
print add(lst,0)
第四種:reduce方式
lst = [1,2,3,4,5]
print reduce(lambda x,y:x+y,lst)
lst = [1,2,3,4,5]
print reduce(lambda x,y:x+y,lst,0)
def add(x,y):
return x+y
print reduce(add, lst)
def add(x,y):
return x+y
print reduce(add, lst,0)
有一個序列集合,例如[1,1,2,3,2,3,3,5,6,7,7,6,5,5,5],統計這個集合所有鍵的重復個數,例如1出現了兩次,2出現了兩次等。大致的思路就是用字典存儲,元素就是字典的key,出現的次數就是字典的value。方法依然很多
第一種:for循環(huán)判斷
def statistics(lst):
dic = {}
for k in lst:
if not k in dic:
dic[k] = 1
else:
dic[k] +=1
return dic
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print(statistics(lst))
第二種:比較取巧的,先把列表用set方式去重,然后用列表的count方法
def statistics2(lst):
m = set(lst)
dic = {}
for x in m:
dic[x] = lst.count(x)
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print statistics2(lst)
第三種:用reduce方式
def statistics(dic,k):
if not k in dic:
dic[k] = 1
else:
dic[k] +=1
return dic
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print reduce(statistics,lst,{})
或者
d = {}
d.extend(lst)
print reduce(statistics,d)
通過上面的例子發(fā)現,凡是要對一個集合進行操作的,并且要有一個統計結果的,能夠用循環(huán)或者遞歸方式解決的問題,一般情況下都可以用reduce方式實現。
分享題目:python函數理解,python中關于函數的描述
網頁網址:http://m.rwnh.cn/article14/phjsge.html
成都網站建設公司_創(chuàng)新互聯,為您提供建站公司、全網營銷推廣、動態(tài)網站、網站營銷、搜索引擎優(yōu)化、做網站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯