dict下如何取值_年薪百万之路--第十七天 装饰器(下)和迭代器
一 有參裝飾器
>帶有參數(shù)的函數(shù)裝飾器
為被裝飾對(duì)象添加認(rèn)證功能的裝飾器,實(shí)現(xiàn)的基本形式如下
def deco(func):def wrapper(*args,**kwargs):編寫(xiě)基于文件的認(rèn)證,認(rèn)證通過(guò)則執(zhí)行res=func(*args,**kwargs),并返回resreturn wrapper如果想提供多種不同的認(rèn)證方式以供選擇,單從wrapper函數(shù)的實(shí)現(xiàn)角度改寫(xiě)如下
def auth(func,db_type):def wrapper(*args, **kwargs):name=input('your name>>>: ').strip()pwd=input('your password>>>: ').strip()if db_type == 'file':print('基于文件的驗(yàn)證')if name == 'egon' and pwd == '123':res = func(*args, **kwargs)return reselse:print('user or password error')elif db_type == 'mysql':print('基于mysql的驗(yàn)證')elif db_type == 'ldap':print('基于ldap的驗(yàn)證')else:print('不支持該db_type')return wrapper函數(shù)wrapper需要一個(gè)driver參數(shù),而函數(shù)deco與wrapper的參數(shù)都有其特定的功能,不能用來(lái)接受其他類別的參數(shù),可以在deco的外部再包一層函數(shù)auth,用來(lái)專門(mén)接受額外的參數(shù),這樣便保證了在auth函數(shù)內(nèi)無(wú)論多少層都可以引用到
def auth(db_type):def deco(func):def wrapper(*args, **kwargs):name = input('your name>>>: ').strip()pwd = input('your password>>>: ').strip()if db_type == 'file':print('基于文件的驗(yàn)證')if name == 'egon' and pwd == '123':res = func(*args, **kwargs) # index(1,2)return reselse:print('user or password error')elif db_type == 'mysql':print('基于mysql的驗(yàn)證')elif db_type == 'ldap':print('基于ldap的驗(yàn)證')else:print('不支持該db_type')return wrapperreturn deco想要保留原函數(shù)的文檔和函數(shù)名屬性,需要修正裝飾器
def timer(func):def wrapper(*args,**kwargs):start_time=time.time()res=func(*args,**kwargs)stop_time=time.time()print('run time is %s' %(stop_time-start_time))return reswrapper.__doc__=func.__doc__wrapper.__name__=func.__name__return wrapper上述方式來(lái)實(shí)現(xiàn)保留原函數(shù)屬性過(guò)于麻煩,functools模塊下提供一個(gè)裝飾器wraps專門(mén)用來(lái)
from functools import wrapsdef timer(func):@wraps(func)def wrapper(*args,**kwargs):start_time=time.time()res=func(*args,**kwargs)stop_time=time.time()print('run time is %s' %(stop_time-start_time))return resreturn wrapper>帶有參數(shù)的類裝飾器
#參數(shù)1 : 給修飾的類添加成員屬性和方法 #參數(shù)2 : 給類中的run方法變成屬性class Kuozhan():ad = "我是屬性"def char(self):print("我是方法")def __init__(self,num):self.num = numdef __call__(self,cls):print(cls)if self.num == 1:return self.kuozhan1(cls)elif self.num == 2:return self.kuozhan2(cls)#參數(shù)1的情況:添加成員屬性和方法def kuozhan1(self,cls):def newfunc():cls.ad = Kuozhan.adcls.money = Kuozhan.moneyreturn cls()return newfunc#參數(shù)2的情況:把方法變成屬性def kuozhan2(self,cls):def newfunc():if "run" in cls.__dict__:cls.run = cls.run()return cls()return newfunc # @Kuozhan(1) class MyClass():def run():return "運(yùn)動(dòng)" obj = MyClass() print(obj.ad) obj.money()# @Kuozhan(2) class MyClass():def run():return "運(yùn)動(dòng)" obj = MyClass() print(obj.run)>property
可以把方法變成屬性 : 可以動(dòng)態(tài)的控制屬性的獲取,設(shè)置,刪除相關(guān)操作
@property 獲取屬性
@方法名.setter 設(shè)置屬性
@方法名.deleter 刪除屬性
class MyClass():def __init__(self,name):self.name = name@propertydef username(self):return self.name@username.setterdef username(self,val):self.name = valpass@username.delsterdef username(self):def self.namepass obj = MyClass("小紅") 獲取指的時(shí)候自動(dòng)觸發(fā)@property 裝飾器下的方法 res = obj.username print(res)#設(shè)置值的時(shí)候自動(dòng)觸發(fā)@username.setter裝飾器下的方法 obj.username = "小白" print(obj.username)class Myclass():def __init__(self,name):self.name = name #獲取數(shù)據(jù)def get_username(self):return self.name#設(shè)置數(shù)據(jù)def set_username(self,val):self.name = val#刪除數(shù)據(jù)def del_username(self):del self.name#參數(shù)的順序:獲取,設(shè)置,刪除username = property(get_username, set_username, del_username)obj = MyClass("小白") #獲取值的時(shí)候,執(zhí)行g(shù)et_username下的相關(guān)操作 print(obj.username) #設(shè)置值的時(shí)候,執(zhí)行set_username下的相關(guān)操作 print(obj.username) #刪除值的時(shí)候,執(zhí)行del_username下的相關(guān)操作 del obj.username print(obj.username)二 迭代器
1、什么是迭代器
迭代器指的是迭代取值的工具,迭代是一個(gè)重復(fù)的過(guò)程,每次重復(fù)
都是基于上一次的結(jié)果而繼續(xù)的,單純的重復(fù)并不是迭代
2、為何要有迭代器
迭代器是用來(lái)迭代取值的工具,而涉及到把多個(gè)值循環(huán)取出來(lái)的類型
有:列表、字符串、元組、字典、集合、打開(kāi)文件
上述迭代取值的方式只適用于有索引的數(shù)據(jù)類型:列表、字符串、元組
為了解決基于索引迭代器取值的局限性
python必須提供一種能夠不依賴于索引的取值方式,這就是迭代器
3、如何用迭代器
1、可迭代的對(duì)象
從語(yǔ)法形式上講,內(nèi)置有__iter__方法的對(duì)象都是可迭代對(duì)象,字符串、列表、元組、字典、集合、打開(kāi)的文件都是可迭代對(duì)象
2、調(diào)用可迭代對(duì)象下的__iter__方法會(huì)將其轉(zhuǎn)換成迭代器對(duì)象
3、可迭代對(duì)象與迭代器對(duì)象詳解
可迭代對(duì)象("可以轉(zhuǎn)換成迭代器的對(duì)象"):內(nèi)置有__iter__方法對(duì)象
可迭代對(duì)象.__iter__(): 得到迭代器對(duì)象
迭代器對(duì)象:內(nèi)置有__next__方法并且內(nèi)置有__iter__方法的對(duì)象
迭代器對(duì)象.__next__():得到迭代器的下一個(gè)值
迭代器對(duì)象.__iter__():得到迭代器的本身
4、可迭代對(duì)象:字符串、列表、元組、字典、集合、文件對(duì)象
迭代器對(duì)象:文件對(duì)象
5、for循環(huán)的工作原理:for循環(huán)可以稱之為叫迭代器循環(huán),in后可以跟任意可迭代對(duì)象
1、d.__iter__()得到一個(gè)迭代器對(duì)象 2、迭代器對(duì)象.__next__()拿到一個(gè)返回值,然后將該返回值賦值給k 3、循環(huán)往復(fù)步驟2,直到拋出StopIteration異常for循環(huán)會(huì)捕捉異常然后結(jié)束循環(huán)6、迭代器優(yōu)缺點(diǎn)總結(jié)
6.1 優(yōu)點(diǎn):
I、為序列和非序列類型提供了一種統(tǒng)一的迭代取值方式。
II、惰性計(jì)算:迭代器對(duì)象表示的是一個(gè)數(shù)據(jù)流,可以只在需要時(shí)才去調(diào)用next來(lái)計(jì)算出一個(gè)值,就迭代器本身來(lái)說(shuō),同一時(shí)刻在內(nèi)存中只有一個(gè)值,因而可以存放無(wú)限大的數(shù)據(jù)流,而對(duì)于其他容器類型,如列表,需要把所有的元素都存放于內(nèi)存中,受內(nèi)存大小的限制,可以存放的值的個(gè)數(shù)是有限的。
6.2 缺點(diǎn):
I、除非取盡,否則無(wú)法獲取迭代器的長(zhǎng)度
II、只能取下一個(gè)值,不能回到開(kāi)始,更像是‘一次性的’,迭代器產(chǎn)生后的唯一目標(biāo)就是重復(fù)執(zhí)行next方法直到值取盡,否則就會(huì)停留在某個(gè)位置,等待下一次調(diào)用next;若是要再次迭代同個(gè)對(duì)象,你只能重新調(diào)用iter方法去創(chuàng)建一個(gè)新的迭代器對(duì)象,如果有兩個(gè)或者多個(gè)循環(huán)使用同一個(gè)迭代器,必然只會(huì)有一個(gè)循環(huán)能取到值。
三 生成器
如何得到自定義的迭代器:
在函數(shù)內(nèi)一旦存在yield關(guān)鍵字,調(diào)用函數(shù)并不會(huì)執(zhí)行函數(shù)體代碼
會(huì)返回一個(gè)生成器對(duì)象,生成器即自定義的迭代器
總結(jié)
以上是生活随笔為你收集整理的dict下如何取值_年薪百万之路--第十七天 装饰器(下)和迭代器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 中原信用卡从哪里提额
- 下一篇: 高端装备上市公司股票 有几家大家都得知道