day21(python高級編程,property屬性,生成器,迭代器,閉包,裝飾器)

屬性property

私有屬性添加getter和setter方法

對于類對象的私有屬性,我們不能直接調(diào)用,可以添加方法來調(diào)用。

class Person:

????def __init__(self):

????????pass

????def setAge(self,age):

????????if 0<=age<=100:

????????????self.__age = age

????????else:

????????????self.__age = 16

????????????print('輸入的年齡不符合')

????def getAge(self):

????????return self.__age

p1 = Person()

p1.setAge(10)

print(p1.getAge())

p1.setAge(200)

print(p1.getAge())

結(jié)果:

10

輸入的年齡不符合

16

使用property升級getter和setter方法

class Person:

????def __init__(self):

????????pass

????def setAge(self,age):

????????if 0<=age<=100:

????????????self.__age = age

????????else:

????????????self.__age = 16

????????????print('輸入的年齡不符合')

????def getAge(self):

????????return self.__age

????????age = property(getAge,setAge)

p1 = Person()

p1.age = 10

print(p1.age)

p1.age = 200

print(p1.age)

結(jié)果:

10

入的年齡不符合

16

使用property取代getter和setter方法

class Person:

????def __init__(self):

????????pass

????@property

????def age(self):

????????return self.__age

????@age.setter

????def age(self,age):

????????if 0<=age<=100:

????????????self.__age = age

????????else:

????????????self.__age = 16

????????????print('輸入的年齡不符合')

p1 = Person()

p1.age = 10

print(p1.age)

p1.age = 200

print(p1.age)

結(jié)果:

10

輸入的年齡不符合

16

生成器

通過列表生成式,我們可以直接創(chuàng)建一個列表。但是,受到內(nèi)存限制,列表容量肯定是有限的。而且,創(chuàng)建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數(shù)元素占用的空間都白白浪費了。所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計算的機制,稱為生成器:generator。

創(chuàng)建生成器

1.把列表生成式的[]改成()

如:

[ x*2 for x in range(5)]

改為:

( x*2 for x in range(5))

如果想要打印,可以通過next()獲取生成器的下一個返回值,而且,generator也是可迭代的,所以也可以用循環(huán)遍歷。

2.有的比較復(fù)雜,用類似列表生成式的for循環(huán)無法實現(xiàn)的時候,還可以用函數(shù)來實現(xiàn)。

可以用yield

例如:

def fib(num):

????a,b = 0,1

????while num>0:

????????yield b

????????a,b = b,a+b

????????num-=1


f = fib(5)

print(' ',next(f))

print(' ',next(f))

for i in f:

????print(i)

在上面fib 的例子,我們在循環(huán)過程中不斷調(diào)用 yield ,就會不斷中斷。當(dāng)然要給循環(huán)設(shè)置一個條件來退出循環(huán),不然就會產(chǎn)生一個無限數(shù)列出來。同樣的,把函數(shù)改成generator后,我們基本上從來不會用 next() 來獲取下一個返回值,而是直接使用 for 循環(huán)來迭代。

但是用for循環(huán)調(diào)用generator時,發(fā)現(xiàn)拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中。

send:

執(zhí)行到y(tǒng)ield時,gen函數(shù)作用暫時保存,返回i的值;temp接收下次c.send("python"),send發(fā)送過來的值,c.next()等價c.send(None)。

def nums():

????for i in range(10):

????????ret = yield i

????????if ret == '平方':

????????????print(i**2)

????????elif ret == '立方':

????????????print(i**3)

num = nums()

print(num)

print(next(num))

print(next(num))

print(next(num))

print(next(num))

print(next(num))

print('----------')

num1 = nums()

next(num1)

num1.send('平方')

num1.send('平方')

num1.send('平方')

num1.send('立方')

num1.send('立方')

num1.send('立方')

__next__:作為一個魔法方法,__next__等價于next()

生成器是這樣一個函數(shù),它記住上一次返回時在函數(shù)體中的位置。對生成器函數(shù)的第二次(或第 n 次)調(diào)用跳轉(zhuǎn)至該函數(shù)中間,而上次調(diào)用的所有局部變量都保持不變。

生成器不僅“記住”了它數(shù)據(jù)狀態(tài);生成器還“記住”了它在流控制構(gòu)造(在命令式編程中,這種構(gòu)造不只是數(shù)據(jù)值)中的位置。

生成器的特點:

節(jié)約內(nèi)存

迭代到下一次的調(diào)用時,所使用的參數(shù)都是第一次所保留下的,即是說,在整個所有函數(shù)調(diào)用的參數(shù)都是第一次所調(diào)用時保留的,而不是新創(chuàng)建的

迭代器

迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會后退。

可迭代對象

以直接作用于 for 循環(huán)的數(shù)據(jù)類型有以下幾種:

一類是集合數(shù)據(jù)類型,如 list 、 tuple 、 dict 、 set 、 str 等;

一類是 generator ,包括生成器和帶 yield 的generator function。

這些可以直接作用于 for 循環(huán)的對象統(tǒng)稱為可迭代對象: Iterable 。

判斷是否可以迭代

可以使用 isinstance() 判斷一個對象是否是 Iterable 對象:

from collections import Iterable,Iterator

def f():

????yield 'hello'

print(isinstance(f(),Iterable))

print(isinstance(f(),Iterator))

print(isinstance('abc',Iterable))

print(isinstance('abc',Iterator))

迭代器

可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator。

可以使用 isinstance() 判斷一個對象是否是 Iterator 對象。

iter()函數(shù)

生成器都是 Iterator 對象,但 list 、 dict 、 str 雖然是 Iterable ,卻不是 Iterator 。

把 list 、 dict 、 str 等 Iterable 變成 Iterator 可以使用 iter() 函數(shù)。

name = 'abc'

myIter = iter(name)

print(type(myIter))

print(isinstance(myIter,Iterator))

try:

????print(next(myIter))

????print(next(myIter))

????print(next(myIter))

????print(next(myIter))

except StopIteration as ex:

????print('迭代完了,%s'%ex)

閉包

函數(shù)引用

閉包概念:

在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包。

def test(number):

????'''

????在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,

????那么將這個函數(shù)以及用到的一些變量稱之為閉包

????'''

????def test_in(number_in):

????????print("in test_in 函數(shù), number_in is %d"%number_in)

????????return number+number_in

????#其實這里返回的就是閉包的結(jié)果

????return test_in

#給test函數(shù)賦值,這個20就是給參數(shù)number

ret = test(20)

#注意這里的100其實給參數(shù)number_in

print(ret(100))

#注意這里的200其實給參數(shù)number_in

print(ret(200))

閉包思考:

1.閉包似優(yōu)化了變量,原來需要類對象完成的工作,閉包也可以完成

2.由于閉包引用了外部函數(shù)的局部變量,則外部函數(shù)的局部變量沒有及時釋放,消耗內(nèi)存

裝飾器

裝飾器,功能就是在運行原來功能基礎(chǔ)上,加上一些其它功能,比如權(quán)限的驗證,比如日志的記錄等等。不修改原來的代碼,進行功能的擴展。

比如java中的動態(tài)代理,python的注解裝飾器

其實python的裝飾器,是修改了代碼。

def login(func):

????def inner(a,b):

????????user = input('請輸入用戶名:')

????????psd = input('請輸入密碼:')

????????if user == a and psd == b:

????????????print('Welcome in!')

????????????func(a,b)

????????else:

????????????print('Passward error!')

????return inner

@login

def f1(nowHaveUser,nowHavePsd):

print('f1')

def f2():

print('f2')

def f3():

print('f3')

def f4():

print('f4')

f1('haha','123456')


python解釋器就會從上到下解釋代碼,步驟如下:

1.def login(func):?==>將login函數(shù)加載到內(nèi)存

2.@login

沒錯,?從表面上看解釋器僅僅會解釋這兩句代碼,因為函數(shù)在?沒有被調(diào)用之前其內(nèi)部代碼不會被執(zhí)行。

從表面上看解釋器著實會執(zhí)行這兩句,但是@login這一句代碼里卻有大文章,@函數(shù)名?是python的一種語法糖。

上例@login內(nèi)部會執(zhí)行一下操作:

執(zhí)行l(wèi)ogin函數(shù)

執(zhí)login1函數(shù)?,并將@login下面的函數(shù)作為login函數(shù)的參數(shù),即:@login等價于login(f1)所以,內(nèi)部就會去執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內(nèi)容

  • 1.1==,is的使用 ·is是比較兩個引用是否指向了同一個對象(引用比較)。 ·==是比較兩個對象是否相等。 1...
    TENG書閱讀 739評論 0 0
  • 基礎(chǔ)1.r''表示''內(nèi)部的字符串默認不轉(zhuǎn)義2.'''...'''表示多行內(nèi)容3. 布爾值:True、False(...
    neo已經(jīng)被使用閱讀 1,706評論 0 5
  • 住的這個小區(qū)也建好幾年了,怎么周圍一直在裝修,鉆啊鉆啊。于是開大音樂,擋住鉆的聲音,周期性重復(fù)的聲音實在是亂人心緒...
    KevinCool閱讀 833評論 1 1
  • 今晚吃秘魯菜,酸酸辣辣的味道,一不留神吃多了。席間,突然想起已經(jīng)兩年多沒有跟納豆先生說:我從明天開始減肥這句話了...
    瘋小蝦閱讀 864評論 11 11
  • 有時候當(dāng)被別人說到“你變了”之類的話,總是會不由自主的感到緊張焦慮 緊張別人說起自己的變是怎樣一種口吻和態(tài)度,更怕...
    藝妹哦耶耶閱讀 470評論 1 2