python生成器和装饰器_python之yield与装饰器
防偽碼:忘情公子著
python中的yield:
在之前發布的《python之列表解析與生成器》中我們有提到過,生成器所實現的是跟列表解析近似的效果,但是我們不能對生成器做一些屬于列表解析的操作。
因為生成器本身就不是一個列表,它只是模擬了一個類似列表的行為,因此,施加在列表中的很多操作,對生成器而言是無效的。
由于生成器表達式并不會直接創建出序列形式的列表,因此不能對其進行索引、切片,不能執行任何常規的列表操作。比如:彈出元素(pop())、添加元素(append())等等。但是我們可以通過list函數將生成器轉換成列表。In?[1]:?list((i**2?for?i?in?range(1,11)))
Out[1]:?[1,?4,?9,?16,?25,?36,?49,?64,?81,?100]
很多情況下我們需要生成更為復雜的結果,又不想基于某個列表來實現,但是簡單的使用一個生成器表達式很難實現此種行為。此時我們可以通過一個自定義函數來完全實現類似的效果。In?[2]:?def?genNum(x):
...:?????y?=?0
...:?????while?y?<=?x:
...:?????????yield?y
...:?????????y?+=?1
...:
In?[3]:?g1?=?genNum(10)
In?[4]:?type(g1)
Out[4]:?generator
In?[5]:?g1.next()
Out[5]:?0
In?[6]:?g1.next()
Out[6]:?1
In?[7]:?g1.next()
Out[7]:?2
In?[8]:?g1.next()
Out[8]:?3
In?[9]:?g1.next()
Out[9]:?4
In?[10]:?g1.next()
Out[10]:?5
In?[11]:?g1.next()
Out[11]:?6
In?[12]:?g1.next()
Out[12]:?7
In?[13]:?g1.next()
Out[13]:?8
In?[14]:?g1.next()
Out[14]:?9
In?[15]:?g1.next()
Out[15]:?10
In?[16]:?g1.next()
---------------------------------------------------------------------------
StopIteration?????????????????????????????Traceback?(most?recent?call?last)
?in?()
---->?1?g1.next()
StopIteration:
yield本身并不是一個返回值,卻能夠生成一個生成器對象。
如上例所看到的,當我們在函數中使用yield,會返回一個生成器對象。
求1到20以內所有正整數的平方:In?[17]:?def?genNum(n):
...:?????count?=?1
...:?????while?count?<=?n:
...:?????????yield?count?**?2
...:?????????count?+=?1
...:
In?[18]:?g1?=?genNum(20)
In?[19]:?for?i?in?g1:
...:?????print?i
...:
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
Python中的裝飾器:
裝飾器即函數裝飾器,裝飾器自身是一個函數,它的主要目的在于能夠把其它函數的功能增強。
裝飾器能夠實現函數代碼重用,或者說函數功能在不同環境中重用。
裝飾器是一個非常著名的設計模式,經常用于比如插入日志、性能測試、事務處理等。
裝飾器可以抽離出大量的函數中與函數無關的功能,把函數本身只作為一個核心,在必要時如果函數的核心功能不夠,就用裝飾器裝飾一下本次調用所需要的功能,于是運行結束了,下次當需要其它功能時再用裝飾器給重新裝飾一下就可以了,這就是裝飾器。
裝飾器需要接受一個函數對象作為其參數,而后對此函數做包裝,以對此函數進行增強。
不帶參數的func(被裝飾的函數):In?[20]:?def?decorative(func):
...:?????def?wrapper():????#定義一個包裝器
...:?????????print?"Please?say?something:?"
...:?????????func()????#調用func,這個func是我們自己定義的
...:?????????print?"No?zuo?no?die..."
...:?????return?wrapper
...:
In?[21]:?@decorative????#使用@符號調用裝飾器
...:?def?show():????#定義func,名字取什么都無所謂,它只是用來傳給裝飾器中的func參數
...:?????print?"I‘m?from?Mars."
...:?show()
...:
Please?say?something:
I‘m?from?Mars.
No?zuo?no?die...
如上例所示,show函數本身只有一個print語句,而使用裝飾器以后,就變成了三個print,這里的print可以改成任何其它的語句,這就是函數的裝飾器。
帶參數的func(被裝飾的函數):In?[22]:?def?decorative(func):
...:?????def?wrapper(x):
...:?????????print?"Please?say?something...>"
...:?????????func(x)
...:?????????print?"no?zuo?no?die..."
...:?????return?wrapper
...:
In?[23]:?@decorative
...:?def?show(x):
...:?????print?x
...:
In?[24]:?show("hello,mars.")
Please?say?something...>
hello,mars.
no?zuo?no?die...
總結
以上是生活随笔為你收集整理的python生成器和装饰器_python之yield与装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python相同key合并value_p
- 下一篇: python 监视图_python获取z