摘要:可以通過定位參數和關鍵字參數傳入的形參多數函數的參數屬于此類。就像數據格式化一樣數據帶上標簽自行創建函數它會自行創建函數。創建的函數會在對象上調用參數指定的方法自己創建函數凍結參數這個高階函數用于部分應用一個函數。
高階函數
def reverse(word): return word[::-1] fruits = ["strawberry", "fig", "apple", "cherry", "raspberry", "banana"] print(reverse("testing")) print(sorted(fruits, key=reverse))all 和 any 也是內置的歸約函數。
如果 iterable 的每個元素都是真值,返回 True;all([]) 返回True。
只要 iterable 中有元素是真值,就返回 True;any([]) 返回False。
匿名函數fruits = ["strawberry", "fig", "apple", "cherry", "raspberry", "banana"] print(sorted(fruits, key=lambda word: word[::-1]))可調用對象
如果類定義了 call 方法,那么它的 實例 可以作為函數調用。
因此判斷對象能否調用,最安全的方法是使用內置的 callable() 函數
實現 call 方法的類是創建函數類對象的簡便方式,
函數內省用戶定義的函數的屬性 page 252
案例 生成html標簽的函數def tag(name, *content, cls=None, **attrs): """生成一個或多個HTML標簽""" if cls is not None: attrs["class"] = cls if attrs: attr_str = "".join(" %s="%s"" % (attr, value) for attr, value in sorted(attrs.items())) else: attr_str = "" if content: return " ".join("<%s%s>%s%s>" % (name, attr_str, c, name) for c in content) else: return "<%s%s />" % (name, attr_str) print(tag("br")) print(tag("p", "hello")) print(tag("p", "hello", "world")) print(tag("p", "hello", "world", cls="sidebar"))獲取關于參數的信息
import bobo @bobo.query("/") def hello(person): return "Hello %s!" % person
bobo.query 裝飾器把一個普通的函數(如 hello)與框架的請求處理
機制集成起來了。
Bobo 會內省 hello 函數,發現它需要一個名為 person
的參數,然后從請求中獲取那個名稱對應的參數,將其傳給 hello 函
數,因此程序員根本不用觸碰請求對象。
使用 inspect 模塊
from clip import clip from inspect import signature sig = signature(clip) print(sig) print(str(sig)) for name, param in sig.parameters.items(): print(param.kind, ":", name, "=", param.default)
inspect.signature 函數返回一個inspect.Signature 對象
它有一個 parameters 屬性,這是一個有序映射,
把參數名和 inspect.Parameter 對象對應起來。
各個Parameter 屬性也有自己的屬性,
例如 name、default 和 kind。特殊的 inspect._empty 值表示沒有默認值
kind 屬性的值是 _ParameterKind 類中的 5 個值之一,列舉如下。
POSITIONAL_OR_KEYWORD
可以通過定位參數和關鍵字參數傳入的形參(多數 Python 函數的參數屬于此類)。
VAR_POSITIONAL
定位參數元組。
VAR_KEYWORD
關鍵字參數字典。
KEYWORD_ONLY
僅限關鍵字參數(Python 3 新增)。
POSITIONAL_ONLY
僅限定位參數;inspect.Signature 對象有個 bind 方法,
它可以把任意個參數綁定到簽名中的形參上,所用的規則與實參到形參的匹配方式一樣。
框架可以使用這個方法在真正調用函數前驗證參數,
示例 5-18 把tag 函數(見示例 5-10)的簽名綁定到一個參數字典
上
>>> import inspect >>> sig = inspect.signature(tag) ? >>> my_tag = {"name": "img", "title": "Sunset Boulevard", ... "src": "sunset.jpg", "cls": "framed"} >>> bound_args = sig.bind(**my_tag) ? >>> bound_args? >>> for name, value in bound_args.arguments.items(): ? ... print(name, "=", value) ... name = img cls = framed attrs = {"title": "Sunset Boulevard", "src": "sunset.jpg"} >>> del my_tag["name"] ? >>> bound_args = sig.bind(**my_tag) ? Traceback (most recent call last): ... TypeError: "name" parameter lacking default value
? 把一個字典參數傳給 .bind() 方法。
? 得到一個 inspect.BoundArguments 對象。
? 迭代 bound_args.arguments(一個 OrderedDict 對象)中的元
素,顯示參數的名稱和值。
? 把必須指定的參數 name 從 my_tag 中刪除。
? 調用 sig.bind(**my_tag),拋出 TypeError,抱怨缺少 name 參
數。
def clip(text: str, max_len: "int > 0" = 80) -> str: print(text, max_len) clip("sdf", 18) print(clip.__annotations__)
如果想注解返回值,在 ) 和函數聲明末尾的 : 之間添加 -> 和一個表達式。
各個參數可以在 : 之后增加注解表達式。如果參數有默認值,注解放在參數名和 = 號之間。
注解不會做任何處理,只是存儲在函數的 annotations 屬性(一operator模塊 reduce計算階乘
個字典)中:
from functools import reduce # 階乘 def fact(n): print(reduce(lambda a, b: a * b, range(1, n + 1))) # operator.mul 函數計算階乘 from functools import reduce from operator import mul def fact2(n): return reduce(mul, range(1, n + 1)) print(fact2(3))itemgetter
展示了 itemgetter 的常見用途:根據元組的某個字段給元
組列表排序。在這個示例中,按照國家代碼(第 2 個字段)的順序打印
各個城市的信息。
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)), ] ### 演示使用 itemgetter 排序一個元組列表 from operator import itemgetter for city in sorted(metro_data, key=itemgetter(1)): print(city)
如果把多個參數傳給 itemgetter,它構建的函數會返回提取的值構成
的元組:
cc_name = itemgetter(1, 0) for city in metro_data: print(cc_name(city))attrgetter
此外,如果參數名中包含 .(點號),attrgetter 會深
入嵌套對象,獲取指定的屬性。
from collections import namedtuple 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)), ] ## 就像數據格式化一樣 數據帶上標簽 LatLong = namedtuple("LatLong", "lat long") Metropolis = namedtuple("Metropolis", "name cc pop coord") metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long)) for name, cc, pop, (lat, long) in metro_data] print(metro_areas[0]) print(metro_areas[0].coord.lat) # from operator import attrgetter name_lat = attrgetter("name", "coord.lat") for city in sorted(metro_areas, key=attrgetter("coord.lat")): print(name_lat(city))methodcaller 自行創建函數
它會自行創建函數。methodcaller 創建的函數會在對象上調用參數指定的方法
自己創建函數
from operator import methodcaller s = "The time has come" upcase = methodcaller("upper") print(upcase) hiphenate = methodcaller("replace", " ", "-") print(hiphenate(s))functools.partial凍結參數
functools.partial 這個高階函數用于部分應用一個函數。部分應用
是指,基于一個函數創建一個新的可調用對象,把原函數的某些參數固定。
from operator import mul from functools import partial print(mul(3, 7)) # 第一個函數, 第二個固定的參數 triple = partial(mul, 3) print(list(map(triple, range(1, 10))))小總結 高階函數
接受函數為參數,或者把函數作為結果返回的函數是高階函數.
Python 中常用的高階函數有內置函數
sorted、min、max 和 functools. partial
實例 直接函數化運行從 lambda 表達式創建的簡單函數到實現__call__ 方法的類實例。
這些可調用對象都能通過內置的callable() 函數檢測。
函數注解在 inspect 模塊的幫助下,可以讀取它們。
例如,Signature.bind 方法使用靈活的規則把實參綁定到形參上,這與 Python 使用的規則一樣。
operator 模塊介紹了 operator 模塊中的一些函數,
以及functools.partial 函數,
有了這些函數,函數式編程就不太需要功能有限的 lambda 表達式了
其他all 和 any 也是內置的歸約函數.
用來判斷是否所有都為真,或者有一個為真
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41640.html
摘要:在復雜的情況下,需要具體策略維護內部狀態時,可能需要把策略和享元模式結合起來。函數比用戶定義的類的實例輕量,而且無需使用享元模式,因為各個策略函數在編譯模塊時只會創建一次。 一等函數實現設計模式 經典的策略模式定義 定義一系列算法,把它們一一封裝起來,并且使它們可以相互替換。本模式使得算法可以獨立于使用它的客戶而變化。 案例 假如一個網店制定了下述折扣規則。 有 1000 或以上積分...
摘要:高程讀書筆記第五章類型創建實例的方式有兩種。第一種是使用操作符后跟構造函數,另一種方式是使用對象字面量表示法。 JS高程讀書筆記--第五章 Object類型 創建Object實例的方式有兩種。第一種是使用new操作符后跟Object構造函數,另一種方式是使用對象字面量表示法。 在通過對象字面量定義對象時,實際上不會調用Object構造函數 訪問對象屬性時可以使用點表示法和方括號表示法。...
摘要:比如,你可以建立一個,選出熱量超過卡路里的頭三道菜請注意也可以用在無序流上,比如源是一個。跳過元素流還支持方法,返回一個扔掉了前個元素的流。一般來說,應該使用來對這種流加以限制,以避免打印無窮多個值。 一、篩選和切片 1.用謂詞篩選 Streams接口支持filter方法。該操作會接受一個謂詞(一個返回boolean的函數)作為參數,并返回一個包括所有符合謂詞的元素的流。例如篩選出所有...
摘要:跳過元素流還支持方法,返回一個扔掉了前個元素的流。歸約到目前為止,我們見到過的終端操作都是返回一個之類的或對象等。這樣的查詢可以被歸類為歸約操作將流歸約成一個值。通過反復使用加法,你把一個數字列表歸約成了一個數字。 使用流 在上一篇的讀書筆記中,我們已經看到了流讓你從外部迭代轉向內部迭代。這樣,你就用不著寫下面這樣的代碼來顯式地管理數據集合的迭代(外部迭代)了: /** * 菜單 ...
摘要:第三個問題查找所有來自于劍橋的交易員,并按姓名排序。第六個問題打印生活在劍橋的交易員的所有交易額。第八個問題找到交易額最小的交易。 付諸實戰 在本節中,我們會將迄今學到的關于流的知識付諸實踐。我們來看一個不同的領域:執行交易的交易員。你的經理讓你為八個查詢找到答案。 找出2011年發生的所有交易,并按交易額排序(從低到高)。 交易員都在哪些不同的城市工作過? 查找所有來自于劍橋的交易...
閱讀 5265·2021-09-22 15:59
閱讀 1856·2021-08-23 09:42
閱讀 2561·2019-08-29 18:42
閱讀 3444·2019-08-29 10:55
閱讀 2058·2019-08-27 10:57
閱讀 1759·2019-08-26 18:27
閱讀 2722·2019-08-23 18:26
閱讀 2912·2019-08-23 14:40