20200206
##命名空間(namespace)
指的是變量存儲(chǔ)的位置崇裁,每一個(gè)變量都需要存儲(chǔ)到指定的命名空間中
每一個(gè)作用域都會(huì)有一個(gè)它對(duì)應(yīng)的命名空間
全局命名空間首懈,用來(lái)保存全局變量,函數(shù)命名空間用來(lái)保存函數(shù)中的變量
命名空間實(shí)際上就是一個(gè)字典脊髓,是一個(gè)專門(mén)用來(lái)存儲(chǔ)變量的字典。
locals()用于獲取當(dāng)前作用域的命名空間
r如果在全局作用域中調(diào)用locals()則獲取全局命名空間,如果在函數(shù)作用域中調(diào)用locals()
返回一個(gè)字典
示例代碼:
scope=locals()
print(scope)
print(scope['a'])
在函數(shù)內(nèi)部locals()會(huì)獲取函數(shù)的命名空間押赊,使用globals()獲取全局命名空間。
可以使用locals()可以來(lái)操控函數(shù)的命名空間包斑,但是不建議這么操作流礁。
##遞歸
1.基線條件(問(wèn)題可以被分解為的最小問(wèn)題,當(dāng)滿足基線條件時(shí)罗丰,遞歸就不再執(zhí)行了)
2.遞歸條件(將問(wèn)題繼續(xù)分解的條件)
遞歸編寫(xiě)起來(lái)容易神帅,不容易閱讀。
循環(huán)編寫(xiě)起來(lái)難萌抵,容易閱讀找御。
問(wèn)題:求解10的階乘
示例代碼:
def factorial1(n):
'''
求解任意數(shù)的階乘
參數(shù):
n要求階乘的數(shù)字
'''
????result=n
????for i in range(1,n):
????????result*=i
????????return? result
def factorial2(n):
'''
求解任意數(shù)的階乘
參數(shù):
n要求階乘的數(shù)字
'''
#基線條件元镀,判斷n是否為1,若為1霎桅,不再繼續(xù)栖疑。
????if n==1:
????????return 1
????return? n*factorical2(n-1)
函數(shù)power為任意數(shù)字做冪運(yùn)算
def power(n,i):
????if i==1:
????????return n
????ruturn n*power(n,i-1)
判斷回文字符串,是的話返回ture,反之flase
def huiwen(str):
????if len(s)<2:
????????return ture
????elif s[0]!=s[-1]:
????????return false
????return huiwen(s[1:-1])
##高階函數(shù)
在python中滔驶,函數(shù)是一等對(duì)象
一等對(duì)象一般都會(huì)具有如下特點(diǎn):
對(duì)象在運(yùn)行時(shí)創(chuàng)建
能賦值給變量或作為數(shù)據(jù)結(jié)構(gòu)中的元素
能作為參數(shù)傳遞
能作為返回值返回
高階函數(shù)至少要符合以下兩個(gè)條件:
接收函數(shù)作為參數(shù)或者函數(shù)作為返回值的函數(shù)
實(shí)際上是將函數(shù)中保存的代碼傳輸至函數(shù)中
應(yīng)用場(chǎng)景:
定義函數(shù)遇革,可以將指定列表中的所有的偶數(shù),保存到一個(gè)新的列表中進(jìn)行返回
def fn(lst):
#創(chuàng)建新列表
????new_list=[]
#對(duì)列表進(jìn)行篩選
????for n in lst:
????????if n%2==0:
????????????new_list.append(n)
????????return new_list
#定義一個(gè)函數(shù)揭糕,用來(lái)檢查一個(gè)任意的數(shù)字是否為偶數(shù)
def fn2(i):
? ? if i%2==0:
? ? ? ? return True
? ? return False
#定義一個(gè)函數(shù)澳淑,用來(lái)檢查一個(gè)任意的數(shù)字是否大于5
def fn3(i):
? ? if i>5:
? ? ? ? return True
? ? return False
def fn(func,lst):
? ? # 創(chuàng)建新列表
? ? new_list = []
? ? # 對(duì)列表進(jìn)行篩選
? ? for n in lst:
? ? ? ? if func(n):
? ? ? ? ? ? new_list.append(n)
? ? return new_list
#filter()可以從序列這種過(guò)濾出符合條件的元素,保存到一個(gè)新的序列中
參數(shù):
1.函數(shù)插佛,根據(jù)該函數(shù)來(lái)過(guò)濾序列(可迭代的結(jié)構(gòu))
2.需要過(guò)濾的序列(可迭代的結(jié)構(gòu))
返回值:
過(guò)濾后的新序列(可迭代的結(jié)構(gòu))
print(list(filter(fn,l)))
##匿名函數(shù)lamba
lambda函數(shù)表達(dá)式專門(mén)來(lái)創(chuàng)建一些簡(jiǎn)單的函數(shù)杠巡,是創(chuàng)建函數(shù)的又一種方式.
語(yǔ)法:lambda 參數(shù)列表:返回值
匿名函數(shù)一般都是作為參數(shù)使用,在其他地方一般不會(huì)使用
def fn5(a,b):
? ? return a+b
#也可以將匿名函數(shù)賦值給一個(gè)變量雇寇,一般不會(huì)這么做
lambda a,b:a+b
filter(fn5,l)
filter(lambda a,b:a+b,l)
map()函數(shù)可以對(duì)對(duì)象中所有元素做指定的操作氢拥,然后添加到一個(gè)新的對(duì)象中進(jìn)行返回。
map(lambda i:i+1,l)
#定義一個(gè)函數(shù)锨侯,用來(lái)檢查一個(gè)任意的數(shù)字是否為偶數(shù)
def fn2(i):
????if i%2==0:
????????return True
? ? return False
#定義一個(gè)函數(shù)嫩海,用來(lái)檢查一個(gè)任意的數(shù)字是否大于5
def fn3(i):
????if i>5:
????????return True
? ? return False
def fn(func,lst):
# 創(chuàng)建新列表
? ? new_list = []
# 對(duì)列表進(jìn)行篩選
? ? for nin lst:
????????if func(n):
????????????new_list.append(n)
????????return new_list
##匿名函數(shù)lamba
lambda函數(shù)表達(dá)式專門(mén)來(lái)創(chuàng)建一些簡(jiǎn)單的函數(shù),是創(chuàng)建函數(shù)的又一種方式:
def fn5(a,b):
return a+b
#也可以將匿名函數(shù)賦值給一個(gè)變量囚痴,一般不會(huì)這么做
lambda a,b:a+b
filter(fn5,l)
filter(lambda a,b:a+b,l)
map()函數(shù)可以對(duì)對(duì)象中所有元素做指定的操作叁怪,然后添加到一個(gè)新的對(duì)象中進(jìn)行返回。
##sort
該方法用來(lái)對(duì)列表中的元素進(jìn)行排序
sort()默認(rèn)是直接比較列表中元素的大小
sort()可以接收一個(gè)關(guān)鍵字參數(shù)深滚,key
key作為函數(shù)的一個(gè)參數(shù)奕谭,當(dāng)設(shè)置了函數(shù)作為參數(shù)
每次都會(huì)一列表中的一個(gè)元素作為參數(shù)來(lái)調(diào)用函數(shù),并且使用函數(shù)的返回值來(lái)比較元素的大小
l=['a','vv','cccc','dddddd']
l.sort(key=len)
print(l)
l.sort()
print(l)
sorted()
這個(gè)函數(shù)和sort()的用法基本一致痴荐,但是sorted()可以對(duì)任意的序列進(jìn)行排序
sorted排序不會(huì)影響原來(lái)的序列血柳,而是返回一個(gè)新的序列
print(sorted(l,key=len))
##閉包
函數(shù)作為返回值返回
通過(guò)閉包可以創(chuàng)建一些只有當(dāng)前函數(shù)能訪問(wèn)的變量
形成閉包的條件
1.函數(shù)的嵌套
2.將函數(shù)作為返回值進(jìn)行返回
3.內(nèi)部函數(shù)必須使用外部函數(shù)的變量
使用閉包主要是想隱藏不想讓他人看到的數(shù)據(jù)
def fn():
#函數(shù)內(nèi)部定義一個(gè)函數(shù)
? ? def inner():
????????print('wo')
????return inner
#r是一個(gè)函數(shù),是調(diào)用fn()后的返回的函數(shù)
#這個(gè)函數(shù)是在fn()內(nèi)部定義的生兆,并不是全局函數(shù)
#所以這個(gè)函數(shù)總是能訪問(wèn)到fn()函數(shù)內(nèi)的變量
r=fn()
print(r)
#求多個(gè)數(shù)的平局值
nums=[11,2,34,33]
print(sum(nums)/len(nums))
def make_average()
????nums=[]
????def average(n):
????????nums.append(n)
????????return sum(nums)/len(nums)
return average
##裝飾器
創(chuàng)建幾個(gè)函數(shù)
def add(a,b):
????r=a+b
????return r
def mul(a,b):
????r=a*b
????return r
r=add(1122,22)
print(r)
#我們不希望在不修改原函數(shù)的情況下难捌,對(duì)函數(shù)進(jìn)行擴(kuò)展
def fn():
????print('我是fn函數(shù)')
def fn2():
????print('程序開(kāi)始執(zhí)行')
????fn()
????print('程序執(zhí)行結(jié)束')
def new_add(a,b):
????print('程序開(kāi)始執(zhí)行')
????r=add(a,b)
????print('程序執(zhí)行結(jié)束')
????return r
r=new_add(11,22)
print(r)
#上邊的方式在不修改源碼的情況下,對(duì)函數(shù)進(jìn)行擴(kuò)展鸦难,但是每擴(kuò)展一個(gè)函數(shù)需要手動(dòng)創(chuàng)建一個(gè)函數(shù)
#為了解決這個(gè)問(wèn)題根吁,我們創(chuàng)建一個(gè)函數(shù),讓這個(gè)函數(shù)自動(dòng)幫助我們創(chuàng)建生產(chǎn)函數(shù)
def begin_end(old):
'''
? ? 用于對(duì)其他函數(shù)進(jìn)行擴(kuò)展合蔽,是其他函數(shù)在執(zhí)行前打印開(kāi)始執(zhí)行击敌,執(zhí)行后打印執(zhí)行結(jié)束
? ? 參數(shù):old要擴(kuò)展的函數(shù)'''
? ? def new_function(*args,**kwargs):
????????print('程序開(kāi)始執(zhí)行')
????????r = old(*args,**kwargs)
????????print('程序執(zhí)行結(jié)束')
????????return r
????#返回新函數(shù)
? ? return new_function
#像begin_end()這種函數(shù),我們成為裝飾器辈末,通過(guò)裝飾器愚争,可以在不修改原函數(shù)的情況下對(duì)函數(shù)進(jìn)行修改
#在定義函數(shù)時(shí),可以通過(guò)@裝飾器挤聘,來(lái)使用指定的裝飾器轰枝,同時(shí)可以為多個(gè)函數(shù)指定多個(gè)裝飾器
#多個(gè)裝飾器的時(shí)候,從內(nèi)往外進(jìn)行裝飾组去。
#典型用法:
@begin_end
def say_hello():
????print('大家好')
#希望函數(shù)可以在計(jì)算前鞍陨,打印開(kāi)始計(jì)算值,計(jì)算結(jié)束后打印計(jì)算完畢
#我們可以直接修改函數(shù)中的代碼完成需求从隆,但是會(huì)產(chǎn)生以下一些問(wèn)題:
#1.函數(shù)多诚撵,修改會(huì)方便
#2.后期不方便維護(hù)
#3.違反開(kāi)閉原則(OCP)? 程序的設(shè)計(jì),要求開(kāi)發(fā)對(duì)程序的擴(kuò)展键闺,要關(guān)閉對(duì)程序的修改