這周由於期末考的壓力,讀書的進度暫時拖緩了一會。
主要講講函式這一節學到的東西吧,因為字串那一節感覺自己只學了一些概念。
首先是一等物件的定義:
1.在執行時建立
2.能賦值給變數或者資料結構中的元素
3.能作為引數傳給函式
4.能作為函式的返回結果
函式就是一等物件,也就是說上面所有的點它都能做得到。
5.1 把函式看成物件
1.函式名.__doc__讀取函式的文件資訊
2.函式名字其實就和普通變數沒什麼2樣,只是呼叫函式時得加括號,這是因為它實現了callable方法。也就是說我們完全可以把現有的函式名稱賦值給某個變數,那那個變數能更這個函式做同樣的工作。
5.2 高階函式
1.sort 和 sorted 的key 方法
2.列表推導是在某種程度上可以代替map + filter 的組合的
list(map(factorial, filter(lambda n: n%2, range(6))))
如上面這個例子,先過濾掉偶數, 再對剩下的元素進行階乘運算。
3.用reduce 和 add代替sum
sum(list1)
reduce(add, list1)
以上兩句話是等價的
reduce曾經是內建的,現在在functools 裡
5.3匿名函式
lambda 語句, 但是其中不能賦值也不能用while ,try
5.4可呼叫物件
呼叫運算子()
callable()函式可判斷乙個物件能否被呼叫,返回值是乙個bool
想能用() 實現 __call__就好了
5.5 使用者定義的可呼叫型別
在這裡我們將實現乙個通過類創造出的例項能夠加呼叫運算子的例子
import random
class bingocage:
def __init__(self, items):
self.data = list(items)
random.shuffle(self.data)
def pick(self):
try:
return self.data.pop()
except:
raise lookuperror
def __call__(self):
return self.pick()
以上會讓我們在 呼叫 例項 + ()時能隨機pick乙個值
5.6 函式內省
之前我們說過,函式是一類物件,那這種物件和我們平常定義的類有哪些不同呢?
defa
():
pass
classb:
pass b
=b()
(set
(dir
(a))
-set
(dir
(b)))
5.7 從定位引數到僅限關鍵字引數
體會一下python靈活的引數處理機制
用*args, **attrs 展開可迭代物件,並對映到單個引數
接下來看如何簡潔地寫出製作html標籤的做法
deftag
(name, *
content
, cls
=none
, **
attrs):
ifcls
isnot
none
: attrs[
'class'] =
cls
ifattrs:
attr_str =''
.join(
' %s
="%s"'%
(attr, value)
forattr, value
insorted
(attrs.items()))
else
: attr_str =''
ifcontent:
return'\n
'.join(
'<
%s%s
>
%s%s
>'
%(name, attr_str, c, name)
forc
incontent)
else:
return
'<
%s%s
/>'
%(name, attr_str)
(tag(
'br'
(tag(
'p',
'hello'
(tag(
'p',
'hello'
, 'world'
(tag(
name
='p'
, 'hello'
, id=33
)) #通過拆字典
my_tag
(tag(
**my_tag))
(目前還不是太理解為什麼*content這個引數不能以content=...的方式來接收引數,
如果這樣操作的話,實參將被歸在**attrs 那一類)
不通過標準庫來實現記錄函式的簽名
1.__defaults__
檢視函式的引數預設值
2.__code__.co_varnames
檢視函式的引數和在內部定義的一些變數
3.__code__.co_argcount
檢視引數數量
接下來通過inspect來更好地提取函式的資訊
from inspect import signature
sig = signature(函式)
sig.parameters.items()裡儲存了名字和引數組成的元組
用.default 去訪問引數的預設值
用.kind 去訪問引數的型別, 以上都是基於引數而不是名字的操作
通過繫結的形式
新函式 = signature(原函式).bind(**args)
這時這個新函式變成了繫結某些資訊的資訊體
可以用for name, value in 新函式.arguments.items()來訪問引數對映關係。
函式註解
def clip(text, max_len=80)
def clip(text:str, max_len:'int>0'=80) --> str
這個註解就是加在引數:後面,可能就是一種解釋的作用,同時箭頭表明的是返回的註解型別
5.10
支援函式式程式設計的包
operator
書中主要說這個包為算術運算子提供了函式,於是我們可以不用遞迴寫出階乘
deffact(n
): return
reduce
(mul,
range(1
, n+1))
operator還有乙個就是它提供了itemgetter和attrgetter
itemgetter(1) 其實 與 lambda x: x[1] 是等價的
不過它避免了使用匿名函式
例子:sorted(l, key=itemgetter(1))按可迭代物件的第1號索引來排序
但如果是itemgetter(0,1)則是提取出只包含0,1號位的元組
兩個元素及以上則是提取出相對應的元組了
attrgetter也是差不多的
但不同的是他接受屬性
sorted(metro_areas, key=attrgetter('coord.lat'))
這時候讀取的是metro_areas裡的每乙個物件的.coord.let屬性
同樣,當接受多個引數時會返回對應屬性組成的元組
method caller
這個與attrgetter, itemgetter 一樣,它們都返回乙個元素
變成 upper:
a= methodcaller('upper')
a函式就像str.upper()一樣
b = methodcaller('replace', ' ', '-')
b就像.replace(' ', '-')一樣
使用functools.partial來凍結引數
可以使函式構建更加方便,比如我們要算乙個列表中所有元素的三倍,但是不能用乘法
from
operator
import
mul from
functools
import
partial
triple
=partial(mul , 3)
(list
(map
(triple,
range(1
, 10
))))
同樣我們也可以用partial來讓我們的函式變得更具體
比如我們之前定義的tag函式,現在我們只想讓它生成img標籤
picture = partial(tag, 'img', cls='pic-frame')
可以用picture,func來訪問原函式
Fluent Python讀書筆記 二
特殊方法的存在是為了被python直譯器呼叫的,自己並不需要呼叫它。所以使用len object 而不是object.len 如果object是乙個自定義類的物件,python會自己呼叫其中由你實現的 len 方法,而如果是python內建的型別 list,str,bytearray等 cpytho...
Fluent Python讀書筆記 三
容器序列 list tuple和collections.deque這些序列可以存放不同型別的資料。存放的是它們所包含的任意型別的物件的引用。扁平序列 str bytes bytearray memoryview和array.array,這類序列只能容納一種型別。存放的是值而不是引用,扁平序列其實是一...
fluent Python 讀書筆記(二)
對書中1 2 示例中的筆記 1.我們自定義實現乙個類,如何實現這個類的加法,乘法,模等性質呢?以二維向量為例。from math import hypot class vector def init self,x 0,y 0 self.x x self.y y def repr self retur...