導語:本文章記錄了本人在學習Python基礎之函數篇的重點知識及我的心得,打算入門Python的朋友們能夠來一塊兒學習並交流。
本文重點:html
一、瞭解函數在Python中是一等對象;
二、瞭解Python中的可調用對象;
三、掌握正肯定義函數參數的方法;
四、瞭解operator和functools中支持函數式編程的方法。
定義:一等對象是知足以下條件的程序實體:python
在Python中,全部函數都是一等對象。
程序員
定義:接受函數爲參數,或者把函數做爲結果返回的函數是高階函數。
在Python中傳統的高階函數有map,filter,reduce;經常使用的高階函數有內置函數sorted、min、max和functools.partial。正則表達式
定義:可以接受一個可迭代對象並返回單個結果的函數是歸約函數。
reduce就是歸約函數的一種,sum也是一種歸約函數。本章額外介紹兩個內置的歸約函數。express
all(iterable):
可迭代對象中每個元素都是真值則返回True,不然False。
any(iterable)
可迭代對象中存在一個元素是真值則返回True,不然False。
歸約函數會在第14章中討論可迭代對象時重點講解。編程
匿名函數:使用lambda表達式建立的函數,函數自己沒有名字來辨識,於是叫作匿名函數。
句法特色:lambda函數只能使用純表達式,不能賦值,也不能使用while和try等語句。
語法:lambda [arg1 [,arg2,.....argn]]:expression。
優勢:建立方便,簡化代碼工做量。
缺點:代碼可讀性下降。數組
在計算機編程中,自省是指這種能力:檢查某些事物以肯定它是什麼、它知道什麼以及它能作什麼。自省向程序員提供了極大的靈活性和控制力。性能優化
在函數的定義過程可能須要傳入參數,對於函數涉及到的參數分爲如下四種:數據結構
參數組合:當函數涉及到使用多種參數時,定義和傳入的參數需按照的順序:必填參數、默認參數、可變參數、強制關鍵字參數、關鍵字參數.
併發
def func(name,country="China",*,age,**rest): print("name :",name," country :",country," age :",age," rest :",rest) func("Jack","US",age=20) func("Hoya",age=15,male="Boy",height="178",grade="excellent",country="UK") #output: name : Jack country : US age : 20 rest : {} name : Hoya country : UK age : 15 rest : {'male': 'Boy', 'height': '178', 'grade': 'excellent'}
#強制關鍵字參數錯誤傳參 func("Hoya",country="UK",20) SyntaxError: positional argument follows keyword argument #強制關鍵字參數只能利用關鍵字傳入參數
注:函數參數知識引自
做者:東皇Amrzs
能夠經過A=inspect.signature(object)提取關於函數參數的信息;
signature支持signature.parameter方法返回關於參數的有序映射。
signature支持signature.bind(args, *kwargs)方法,此方法可將多個實參綁定到簽名的形參來接受。
註解(annotation)從Python3開始存在,用於爲函數聲明中的參數和返回值附加元數據。只有inspect.signature()能夠提取註解。
本人目前把註解簡單理解爲一種標籤。
定義:支持調用運算符()的對象叫作可調用對象。
判斷方法:利用內置的callable()函數判斷。
Python數據模型包含7種可調用對象:
下面針對類的實例爲示範進行調用操做:
class Text: def __init__(self,text): self.text=str(text) def number_search(self): import re num_search=re.compile(r"\d+") return print("number search :",num_search.findall(self.text)) def __call__(self, *args, **kwargs): return self.number_search() a=Text("asdljlj55fsa56af6af66f598as5asf6af59nf3asf830fa3s") a.number_search() #輸出: number search : ['55', '56', '6', '66', '598', '5', '6', '59', '3', '830', '3']
從中能夠看出,建立函數類對象的簡便方式是實現__call__方法。
相比較命令式編程,函數式編程是經過函數來保存程序的狀態的。或者更準確一點,它是經過函數建立新的參數或返回值來保存程序的狀態的。
認識函數式編程應掌握的兩個本質:
注:函數式編程知識引自
做者:Jan Fan
Python的目標不是變成函數式編程語言,但經過operator和functools等包也能夠進行函數式編程,下面開始介紹這兩個模塊。
本節介紹operator中的mul、itemgetter、attrgetter、methodcaller四種方法。
import operator from _functools import reduce #計算階乘 def fact1(): list1=filter(lambda x: x%2,range(8)) return reduce(operator.mul,list1) print(fact1())#輸出:105
metro_data =[('Tokyo', 'JP', 36.933, (35.689722, 139.691667)), ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)), ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)), ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)), ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))] a=itemgetter(1,0) for i in metro_data: print(a(i))#注意分清楚a和i誰是參數,被處理的可迭代對象是參數。 #輸出: ('JP', 'Tokyo') ('IN', 'Delhi NCR') ('MX', 'Mexico City') ('US', 'New York-Newark') ('BR', 'Sao Paulo')
eg:按照城市經度順序輸出城市名和城市經度
from collections import namedtuple from _operator import attrgetter latlong=namedtuple("latlong","lat long") citydata=namedtuple("citydata", "city ID pop coord") city=[citydata(city,ID,pop,latlong(lat,long)) for city, ID,pop,(lat,long) in metro_data] #拆包+列表推導。拆包注意city,ID,pop,latlong(lat,long)和citydata具名元組的結構對應關係,至於拆包用的變量名字是什麼並不重要,保證可讀性便可。 b=attrgetter("city","coord.lat") #方法1 for i in sorted(city,key=attrgetter("coord.lat")): print(b(i)) #方法2 for i in sorted(city,key=lambda x: x[3][0]): print(b(i)) #輸出 ('Sao Paulo', -23.547778) ('Mexico City', 19.433333) ('Delhi NCR', 28.613889) ('Tokyo', 35.689722) ('New York-Newark', 40.808611)
from operator import methodcaller c=methodcaller("upper") d=methodcaller("islower") print(c("apple"),d("apple")) #輸出 APPLE True.
語法:functools.partial(func, *args, **keywords)
functools.partial適用於函數凍結參數的狀況。凍結參數是指咱們欲調用的函數中的部分或所有參數已經固定,只需補齊剩下的參數調用便可。能夠按照word編輯中的格式刷來理解。
from functools import partial from unicodedata import normalize clean=partial(normalize,"NFC")#字符串格式化,我以爲很像格式刷啊。 e="café" f="cafe\u0301" print(e==f) #False print(clean(e)==clean(f))#True
使用技巧總結:operator中的itemgetter、attrgetter和functools.partial在使用上都須要先構建相似正則表達式的compile partern,即構建對應的itemgetter,attrgetter和partial,而後在partern基礎上傳入待處理對象。
以剛纔的partial舉例就是clean(e),而不是e(clean)。