摘要:本文重點了解函數在中是一等對象了解中的可調用對象掌握正確定義函數參數的方法了解和中支持函數式編程的方法。歸約函數定義能夠接受一個可迭代對象并返回單個結果的函數是歸約函數。
導語:本文章記錄了本人在學習Python基礎之函數篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。
本文重點:
1、了解函數在Python中是一等對象;一、函數是一等對象 1、一等對象
2、了解Python中的可調用對象;
3、掌握正確定義函數參數的方法;
4、了解operator和functools中支持函數式編程的方法。
定義:一等對象是滿足如下條件的程序實體:
在運行時創建;
能賦值給變量或數據結構中的元素;
能作為參數傳給函數;
能作為函數的返回結果。
在Python中,所有函數都是一等對象。
2、高階函數定義:接受函數為參數,或者把函數作為結果返回的函數是高階函數。
在Python中傳統的高階函數有map,filter,reduce;常用的高階函數有內置函數sorted、min、max和functools.partial。
map(function, iterable, ...):
map返回一個迭代器,迭代器是通過function處理可迭代對象中的每個元素產生的返回值的集合。
filter(function, iterable):
filter相當于一個過濾器,以函數返回值為判定條件,篩選出True的元素并放入迭代器中返回。
functools.reduce(function, iterable[, initializer])
reduce對可迭代對象中從左開始元素選出兩個進行函數運算,將返回的運算值作為一個參數繼續與第三個元素進行函數運算,直至迭代完成返回運算值。
定義:能夠接受一個可迭代對象并返回單個結果的函數是歸約函數。
reduce就是歸約函數的一種,sum也是一種歸約函數。本章額外介紹兩個內置的歸約函數。
all(iterable):
可迭代對象中每一個元素都是真值則返回True,否則False。
any(iterable)
可迭代對象中存在一個元素是真值則返回True,否則False。
歸約函數會在第14章中討論可迭代對象時重點講解。
匿名函數:使用lambda表達式創建的函數,函數本身沒有名字來辨識,因而叫做匿名函數。
句法特點:lambda函數只能使用純表達式,不能賦值,也不能使用while和try等語句。
語法:lambda [arg1 [,arg2,.....argn]]:expression。
優點:創建方便,簡化代碼工作量。
缺點:代碼可讀性降低。
在計算機編程中,自省是指這種能力:檢查某些事物以確定它是什么、它知道什么以及它能做什么。自省向程序員提供了極大的靈活性和控制力。
二、函數參數與注解 1、函數參數在函數的定義過程可能需要傳入參數,對于函數涉及到的參數分為以下四種:
必填參數
調用函數必須填寫的參數。在參數中居于靠前位置。
默認參數
當必填參數設置默認值時可選填。注意默認值是不可變對象,否則有邏輯錯誤。
可變參數
用單星號*args表示,即傳入的參數是不定的。*args把參數收到元組中接受。
傳入方式既可以是直接傳入,如func(1, 2, 3);也可以用列表或元組傳入,如func(*(1,2,3))。
強制關鍵字參數
此類參數只能捕獲通過指定關鍵字傳入的參數,無法按照位置順序讀參。定義時前面需放一個*。
關鍵字參數
此參數可填可不填。傳入方式分兩種,一是”傳遞參數名=傳遞參數值”形式的參數,這種方式傳入對位置無要求;二是不寫參數名,按照位置順序傳入參數值。
當關鍵字參數不定時用雙星號**kw表示。**kw把關鍵字參數收到字典中接受。關鍵字參數既可以直接傳入:func(a=1, b=2),又可以先組裝dict,再通過**kw傳入:func(**{"a": 1, "b": 2})。
參數組合:當函數涉及到使用多種參數時,定義和傳入的參數需按照的順序:
必填參數、默認參數、可變參數、強制關鍵字參數、關鍵字參數.
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種可調用對象:
用戶定義的函數
使用def語句或lambda表達式創建。
內置函數
使用CPython實現的函數,如len。
內置方法
使用CPython實現的方法,如list.pop。
方法
在類的定義體中定義的函數。
類
類的實例
如果類定義了__call__方法,這個類的實例可以作為函數調用。
生成器函數
使用yield關鍵字的函數或方法。調用生成器函數返回的對象是生成器。
下面針對類的實例為示范進行調用操作:
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__方法。
四、支持函數式編程的包 1. 函數式編程:相比較命令式編程,函數式編程是通過函數來保存程序的狀態的。或者更準確一點,它是通過函數創建新的參數或返回值來保存程序的狀態的。
認識函數式編程應掌握的兩個本質:
高階函數(higher-order functions)
函數式編程是通過高階函數(higher-order functions)的特性來使其具有更豐富多變的表達能力。如map,filter。
高階函數和一等函數讓基于函數演變的函數式語言表達能力大增,使其能夠用函數構建起更高層更抽象的模塊來解決復雜的問題。
沒有副作用(no side effect)
函數所有功能就是返回一個新的值,沒有其他行為,尤其是不得修改外部變量的值。
使得函數式編程各個獨立的部分的執行順序可以隨意打亂。 而這在命令式編程風格的代碼中是不可能的。
執行順序的自由使其得以衍生出一大堆非常有用的特性,比如無鎖(lock-free)的并發操作、惰性求值(lazy evaluation),還有在編譯器級別上的各種性能優化技術。 特別在并行技術上,Clojure, Haskell, F#, Scala, Erlang這些函數式語言都無一例外地支持強大的并發功能。
當然函數式語言不可能真的就不執行I/O,但它通過一些手段來把I/O的影響限制到最小,比如通過Continuations, Monad等技術。
注:函數式編程知識引自
作者:Jan Fan
Python的目標不是變成函數式編程語言,但通過operator和functools等包也可以進行函數式編程,下面開始介紹這兩個模塊。
2. operator本節介紹operator中的mul、itemgetter、attrgetter、methodcaller四種方法。
operator.mul(a,b)
返回數字a和b的乘積。
import operator from _functools import reduce #計算階乘 def fact1(): list1=filter(lambda x: x%2,range(8)) return reduce(operator.mul,list1) print(fact1())#輸出:105
operator.itemgetter(item or *items)
創建一個接受集合的函數,返回指定索引對應的元素。如果指定索引至少為2個,以元組形式返回查詢結果。
After f = itemgetter(2), the call f(r) returns r[2].
After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]).
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")
operator.attrgetter(attr or *attrs)
創建一個函數,根據名稱訪問對象的屬性,以元組的形式返回。
After f = attrgetter("name"), the call f(b) returns b.name.
After f = attrgetter("name", "date"), the call f(b) returns (b.name, b.date).
After f = attrgetter("name.first", "name.last"), the call f(b) returns (b.name.first, b.name.last).
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)
operator.methodcaller(name[, args...])
自行創建函數,使用對象中支持的方法。args代表函數所需傳入的參數。
After f = methodcaller("name"), the call f(b) returns b.name().
After f = methodcaller("name", "foo", bar=1), the call f(b) returns b.name("foo", bar=1).
from operator import methodcaller c=methodcaller("upper") d=methodcaller("islower") print(c("apple"),d("apple")) #輸出 APPLE True.3. functools.partial
語法:functools.partial(func, *args, **keywords)
functools.partial適用于函數凍結參數的情況。凍結參數是指我們欲調用的函數中的部分或全部參數已經固定,只需補齊剩下的參數調用即可。可以按照word編輯中的格式刷來理解。
from functools import partial from unicodedata import normalize clean=partial(normalize,"NFC")#字符串格式化,我覺得很像格式刷啊。 e="café" f="cafeu0301" 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)。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41474.html
摘要:本文重點了解函數在中是一等對象了解中的可調用對象掌握正確定義函數參數的方法了解和中支持函數式編程的方法。歸約函數定義能夠接受一個可迭代對象并返回單個結果的函數是歸約函數。 本文章記錄了本人在學習Python基礎之函數篇的重點知識及個人心得,歡迎打算入門Python的朋友與我一起學習交流。。 本文重點: 1、了解函數在Python中是一等對象;2、了解Python中的可調用對象;3、掌握...
摘要:元組是靜態數組,它們不可變,且其內部數據一旦創建便無法改變。元組緩存于運行時環境,這意味著我們每次使用元組時無須訪問內核去分配內存。 以下是整理的JavaScript和python的基礎區別的整理: 字符串、列表、元組、字典、集合、函數 字符串 聲明一個字符串 python str = 123 str = 123 Tips: 如果是三個引號的話,那么在py中就是注釋的意思 ...
摘要:元組是靜態數組,它們不可變,且其內部數據一旦創建便無法改變。元組緩存于運行時環境,這意味著我們每次使用元組時無須訪問內核去分配內存。 以下是整理的JavaScript和python的基礎區別的整理: 字符串、列表、元組、字典、集合、函數 字符串 聲明一個字符串 python str = 123 str = 123 Tips: 如果是三個引號的話,那么在py中就是注釋的意思 ...
摘要:一等函數在中,函數是一等對象。匿名函數關鍵字在表達式內創建匿名函數然而,簡單的句法限制了函數的定義體只能使用純表達式,即函數的定義體中不能賦值,不能使用等語句。匿名函數適合用于作為函數的參數 一等函數 在python中,函數是一等對象。編程語言理論家把一等對象定義為滿足以下條件的程序實體: 在運行時創建 能賦值給變量或數據結構中的元素 能作為參數傳給函數 能作為函數的返回結果 在p...
摘要:函數內省的內容到此結束。函數式編程并不是一個函數式編程語言,但通過和等包的支持,也可以寫出函數式風格的代碼。 《流暢的Python》筆記。本篇主要講述Python中函數的進階內容。包括函數和對象的關系,函數內省,Python中的函數式編程。 1. 前言 本片首先介紹函數和對象的關系;隨后介紹函數和可調用對象的關系,以及函數內省。函數內省這部分會涉及很多與IDE和框架相關的東西,如果平時...
閱讀 2581·2021-11-22 12:01
閱讀 1105·2021-11-15 11:37
閱讀 3685·2021-09-22 14:59
閱讀 1746·2021-09-04 16:45
閱讀 1382·2021-09-03 10:30
閱讀 1013·2021-08-11 11:18
閱讀 2459·2019-08-30 10:53
閱讀 2013·2019-08-29 15:13