函數(shù):
內(nèi)置函數(shù)(鏈接)
一.函數(shù)初始
默認(rèn)參數(shù)的陷阱
默認(rèn)參數(shù)若是可變的數(shù)據(jù)類型,他始終使用的是一個(gè)內(nèi)存地址术幔。
def func1(x,l1=[]):
l1.append(x)
return l1
ret = func1(1)
ret1 = func1(100)
return是函數(shù)結(jié)束的標(biāo)志另萤,函數(shù)內(nèi)可以寫(xiě)多個(gè)return,但只執(zhí)行一次
無(wú)return 返回None
只寫(xiě)return诅挑,后面不寫(xiě)其他內(nèi)容四敞,也會(huì)返回None
return 逗號(hào)分隔多個(gè)值 返回元組
返回多個(gè)值,用多個(gè)變量接收
a,b,c,d = ret_demo2()
形參即變量名拔妥,實(shí)參即變量值
函數(shù)即變量 函數(shù)的賦值 f = func
命名關(guān)鍵字參數(shù):*后定義的參數(shù)忿危,必須被傳值(有默認(rèn)值的除外),且必須按照關(guān)鍵字實(shí)參的形式傳遞
可以保證没龙,傳入的參數(shù)中一定包含某些關(guān)鍵字
def foo(位置形參,*args,默認(rèn)參數(shù),**kwargs):
函數(shù)體
return 返回值
動(dòng)態(tài)參數(shù)
溢出的位置參數(shù)值以元祖形式賦給args ,溢出的關(guān)鍵字參數(shù)以字典的形式賦給kwargs
*args铺厨,**kwargs
函數(shù)定義時(shí):*聚合 *args:實(shí)參里面所有的位置參數(shù)缎玫。
**kwargs:實(shí)參里面所有的關(guān)鍵字參數(shù)。
函數(shù)的調(diào)用時(shí):* 打散解滓。
形參的順序:位置參數(shù)赃磨,*args,默認(rèn)參數(shù),**kwargs洼裤。
二.函數(shù)進(jìn)階
存放名字與值的關(guān)系’的空間起了一個(gè)名字-------命名空間邻辉。
全局名稱空間。
臨時(shí)名稱空間逸邦。
內(nèi)置名稱空間。
全局作用域: 全局名稱空間在扰,內(nèi)置名稱空間缕减。
局部作用域: 局部名稱空間。
取值順序:就近原則芒珠,從小到大桥狡。
加載順序:加載的是名稱空間。
global nonlocal
globals() locals() 以字典形式返回模塊全部全局變量和局部變量
全局作用域:包含內(nèi)置名稱空間皱卓、全局名稱空間
局部作用域:局部名稱空間裹芝,只能在局部范圍內(nèi)生效
- 函數(shù)名的本質(zhì)。
函數(shù)名本質(zhì)上就是函數(shù)的內(nèi)存地址娜汁。
1.可以被引用
2.可以被當(dāng)作容器類型的元素
3.可以當(dāng)作函數(shù)的參數(shù)和返回值
第一類對(duì)象(first-class object)指
1.可在運(yùn)行期創(chuàng)建
2.可用作函數(shù)參數(shù)或返回值
3.可存入變量的實(shí)體嫂易。
- 一句話,函數(shù)名能當(dāng)普通變量用
嵌套函數(shù):
匿名函數(shù):使用一次就釋放
- lambda x,y:x**y
- 匿名函數(shù)主要是和其它函數(shù)搭配使用
高階函數(shù):
變量可以指向函數(shù)掐禁,函數(shù)的參數(shù)能接收變量怜械,那么一個(gè)函數(shù)就可以接收另一個(gè)函數(shù)作為參數(shù),這種函數(shù)就稱之為高階函數(shù)傅事。
只需滿足以下任意一個(gè)條件缕允,即是高階函數(shù)
- 接受一個(gè)或多個(gè)函數(shù)作為輸入
- return 返回另外一個(gè)函數(shù)
def add(x,y,f):
return f(x) + f(y)
遞歸
在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)蹭越。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身障本,這個(gè)函數(shù)就是遞歸函數(shù)。
查看遞歸次數(shù)
n = 1
def func(x):
print(x)
x+=1
func(x)
func(n)
def calc(n):
v = int(n/2)
print(v)
if v > 0:
calc(v)
print(n)
calc(10)
遞歸特性:
- 必須有一個(gè)明確的結(jié)束條件
- 每次進(jìn)入更深一層遞歸時(shí)响鹃,問(wèn)題規(guī)模相比上次遞歸都應(yīng)有所減少
- 遞歸效率不高驾霜,遞歸層次過(guò)多會(huì)導(dǎo)致棧溢出()
應(yīng)用:二分查找
閉包原理
閉包函數(shù):內(nèi)部函數(shù)包含對(duì)外部作用域而非全劇作用域變量的引用,該內(nèi)部函數(shù)稱為閉包函數(shù),并返回.
閉包的意義:返回的函數(shù)對(duì)象买置,不僅僅是一個(gè)函數(shù)對(duì)象寄悯,在該函數(shù)外還包裹了一層作用域,這使得堕义,該函數(shù)無(wú)論在何處調(diào)用猜旬,優(yōu)先使用自己外層包裹的作用域
應(yīng)用領(lǐng)域:延遲計(jì)算(原來(lái)我們是傳參脆栋,現(xiàn)在我們是包起來(lái))
閉包作用:
當(dāng)程序執(zhí)行時(shí),遇到了函數(shù)執(zhí)行洒擦,他會(huì)在內(nèi)存中開(kāi)辟一個(gè)空間椿争,局部名稱空間,
如果這個(gè)函數(shù)內(nèi)部形成了閉包熟嫩,
那么他就不會(huì)隨著函數(shù)的結(jié)束而消失秦踪。
name = 'alex'
def wraaper():
def inner():
print(name)
print(inner.__closure__) # None不是閉包函數(shù)
inner()
return inner
wraaper()
name = 'hqs'
def wraaper(n):
n = 'alex'
def inner():
print(n)
print(inner.__closure__) # cell at 0x000002AD93BF76D8 --> 是閉包函數(shù)
inner()
return inner
wraaper(name)
可迭代對(duì)象:Iterable
: str list dict,tuple,set,range()
對(duì)象內(nèi)部含有iter方法就是可迭代對(duì)象.
print('__iter__' in dir(對(duì)象)) #返回True.False
from collections import Iterable #判斷是否是可迭代對(duì)象
from collections import Iterator #判斷是否是迭代器
print(isinstance('對(duì)象',Iterable)) # True/False
print(isinstance('對(duì)象',Iterator)) # True/False
可迭代對(duì)象滿足可迭代協(xié)議。
迭代器:Iterator
對(duì)象內(nèi)部含有__iter__方法且含有__next__方法就是迭代器.
文件本身就是迭代器對(duì)象
迭代器的缺點(diǎn):
- 取值麻煩掸茅,只能一個(gè)一個(gè)取椅邓,只能往后取,
- 并且是一次性的,無(wú)法用len獲取長(zhǎng)度
可迭代對(duì)象不能取值昧狮,迭代器是可以取值的景馁。
可迭代對(duì)象 --->(轉(zhuǎn)化成)迭代器
迭代器=可迭代對(duì)象.iter() #等于 迭代器=iter(可迭代對(duì)象) #轉(zhuǎn)化
1,將可迭代對(duì)象轉(zhuǎn)化成迭代器。
2逗鸣,調(diào)用next方法取值合住。
3,利用異常處理停止報(bào)錯(cuò)撒璧。
模式for循環(huán)
迭代器 = 可迭代對(duì)象.__iter__()
while 1:
try:
print(迭代器.__next__())
except StopIteration:
break
裝飾器:
開(kāi)放封閉原則:
軟件上線后透葛,對(duì)修改源代碼是封閉的,對(duì)功能的擴(kuò)展功能是開(kāi)放的卿樱。
方案:裝飾器
原則:
* 1僚害,不修改原代碼
* 2,不修改調(diào)用方式
目的:
遵循1和2的基礎(chǔ)上拓展新功能
裝飾器:
裝飾為被裝飾對(duì)象添加新功能
含義:
裝飾器即在不修改被裝飾對(duì)象源代碼與調(diào)用方式的前提下繁调,為被裝飾對(duì)象添加新功能
裝飾器 ==》函數(shù)
被裝飾的對(duì)象 ==》函數(shù)
time.time() 獲取當(dāng)前時(shí)間(s)
生成器:就是自己python用代碼寫(xiě)的迭代器贡珊,生成器的本質(zhì)就是迭代器。
generator是可迭代對(duì)象 , 可用for循環(huán)和next()
用以下兩種方式構(gòu)建一個(gè)生成器:
- 1涉馁,通過(guò)生成器函數(shù)门岔。
- 2,生成器表達(dá)式烤送。
生成器函數(shù) vs 迭代器:
- 迭代器是需要可迭代對(duì)象進(jìn)行轉(zhuǎn)化寒随。可迭代對(duì)象非常占內(nèi)存帮坚。
- 生成器直接創(chuàng)建妻往,不需要轉(zhuǎn)化,從本質(zhì)就節(jié)省內(nèi)存试和。
- send 與next一樣讯泣,也是對(duì)生成器取值(執(zhí)行一個(gè)yield)的方法。
- send 可以給上一個(gè)yield 傳值阅悍。
- 第一次取值永遠(yuǎn)都是next好渠。
- 最后一個(gè)yield 永遠(yuǎn)也得不到send傳的值昨稼。
- yield 將值返回給 生成器對(duì)象.next()
迭代器.next() 相當(dāng)于 next(迭代器)
把函數(shù)做成迭代器
* 對(duì)比return,可以返回多次值拳锚,掛起函數(shù)的運(yùn)行狀態(tài)
創(chuàng)建生成器:如下
def func1(): #生成器函數(shù)
print(1)
count = (yield 6)
print(count)
count1 = (yield 7)
print(count1)
yield 8
g = func1() #調(diào)用生成器函數(shù)創(chuàng)建生成器對(duì)象
print(next(g))
print(g.send('alex'))
print(g.send('alex'))
def cloth2(n):
for i in range(1,n+1):
yield '衣服%s號(hào)' % i
g = cloth2(10000)
for i in range(50):
print(g.__next__()) #停在50的位置
for i in range(50): #從51開(kāi)始
print(g.__next__())
列表推導(dǎo)式
- 循環(huán)模式 : [變量(加工后的變量) for 變量 in iterable]
- 篩選模式 : [變量(加工后的變量) for 變量 in iterable if 條件]
優(yōu)點(diǎn):一行解決假栓,方便。
缺點(diǎn):容易著迷霍掺,不易排錯(cuò)匾荆,不能超過(guò)三次循環(huán)。
列表推導(dǎo)式不能解決所有列表的問(wèn)題杆烁,所以不要太刻意用牙丽。
生成器表達(dá)式:
將列表推導(dǎo)式的 [] 換成() 即可。
三元表達(dá)式:ret = 'true' if 1 == 1 else 'false'