1.lambda匿名函式
(1)f = lambda x: x * x
(2)def build(x, y):
return lambda: x * x + y * y
關鍵字lambda表示匿名函式,冒號前面的x表示函式引數。
匿名函式有個限制,就是只能有乙個表示式,不用寫return,返回值就是該表示式的結果。
2.列表推導式
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
把要生成的元素x * x放到前面,後面跟for迴圈,用中括號括起來,來建立list的方法叫做列表推導式。
>>> [x * x for x in range(1, 11) if x % 2 == 0] #這裡後面是篩選條件,不能加else
[4, 16, 36, 64, 100]
還可以使用兩層迴圈,可以生成全排列:
>>> [m + n for m in 'abc' for n in 'xyz']
['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
3.裝飾器
在**執行期間動態增加功能的方式,稱之為「裝飾器」(decorator)。
乙個完整的decorator的寫法如下:
import functools
def log(func):
@functools.wraps(func)
print('call %s():' % func.__name__)
return func(*args, **kw)
@log
def now():
print('2015-3-25')
>>> now()
call now():
2015-3-25
把@log放到now()函式的定義處,相當於執行了語句:
now = log(now)
或者針對帶引數的decorator:
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return decorator
@log('execute')
def now():
print('2015-3-25')
>>> now()
execute now():
2015-3-25
和兩層巢狀的decorator相比,3層巢狀的效果是這樣的:
>>> now = log('execute')(now)
>>> now.__name__
4.協程
協程看上去是子程式,但執行過程中,在子程式內部可中斷,然後轉而執行別的子程式,在適當的時候再返回來接著執行。
注意,在乙個子程式中中斷,去執行其他子程式,不是函式呼叫,有點類似cpu的中斷。
協程的特點在於是乙個執行緒執行。最大的優勢就是協程極高的執行效率。因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯。
第二大優勢就是不需要多執行緒的鎖機制,因為只有乙個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多執行緒高很多。
因為協程是乙個執行緒執行,那怎麼利用多核cpu呢?最簡單的方法是多程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。
python對協程的支援是通過generator實現的。
在generator中,我們不但可以通過for
迴圈來迭代,還可以不斷呼叫next()
函式獲取由yield
語句返回的下乙個值。
但是python的yield
不但可以返回乙個值,它還可以接收呼叫者發出的引數。
傳統的生產者-消費者模型是乙個執行緒寫訊息,乙個執行緒取訊息,通過鎖機制控制佇列和等待,但一不小心就可能死鎖。
如果改用協程,如下:
def consumer():
r = ''
while true:
n = yield r
if not n:
return
print('[consumer] consuming %s...' % n)
r = '200 ok'
def produce(c):
c.send(none)
n = 0
while n < 5:
n = n + 1
print('[producer] producing %s...' % n)
r = c.send(n)
print('[producer] consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
執行結果:
[producer] producing 1...
[consumer] consuming 1...
[producer] consumer return: 200 ok
[producer] producing 2...
[consumer] consuming 2...
[producer] consumer return: 200 ok
[producer] producing 3...
[consumer] consuming 3...
[producer] consumer return: 200 ok
[producer] producing 4...
[consumer] consuming 4...
[producer] consumer return: 200 ok
[producer] producing 5...
[consumer] consuming 5...
[producer] consumer return: 200 ok
整個流程無鎖,由乙個執行緒執行,produce
和consumer
協作完成任務,所以稱為「協程」,而非執行緒的搶占式多工。
「子程式就是協程的一種特例。」
程式解釋:
在乙個生成器函式未啟動之前,是不能傳遞值進去。也就是說在使用c.send(n)
之前,必須先使用c.send(none)
或者next(c)
來返回生成器的第乙個值。
第一步:執行c.send(none)
,啟動生成器返回第乙個值,n = yield r
,此時r
為空,n
還未賦值,然後生成器暫停,等待下一次啟動。
第二步:生成器返回空值後進入暫停,produce(c)
接著往下執行,進入while
迴圈,此時n
為1
,所以列印:
[producer] producing 1...
第三步:produce(c)
往下執行到r = c.send(1)
,再次啟動生成器,並傳入了引數1
,而生成器從上次n
的賦值語句開始執行,n
被賦值為1
,n
存在,if
語句不執行,然後列印:
[consumer] consuming 1...
接著r
被賦值為'200 ok'
,然後又進入迴圈,執行n = yield r
,返回生成器的第二個值,'200 ok'
,然後生成器進入暫停,等待下一次啟動。
第四步:生成器返回'200 ok'
進入暫停後,produce(c)
往下執行,進入r
的賦值語句,r
被賦值為'200 ok'
,接著往下執行,列印:
[producer] consumer return: 200 ok
以此類推...
當n
為5
跳出迴圈後,使用c.close()
結束生成器的生命週期,然後程式執行結束。
java基礎點總結(1)
最近感覺 寫多了,把基礎都忘了,總結一下,想到什麼寫什麼了 1 基本資料型別 byte short int long float double char boolean 2 運算符號 a 運算子 和 都表示與操作,當且僅當運算子兩邊的運算元都為true時,其結果才為true,否則結果為false。當...
Python入門基礎知識點總結1
python識別符號 在 python 裡,識別符號有字母 數字 下劃線組成。在 python 中,所有識別符號可以包括英文 數字以及下劃線 但不能以數字開頭。python 中的識別符號是區分大小寫的。python有五個標準的資料型別 numbers 數字 string 字串 list 列表 tup...
Python字典dict基礎知識點總結
usr bin env python coding utf 8 time 2020 4 21 19 52 author xuhui file dict.py print print aaaaaaaaa print 字典的建立,字典又叫做雜湊表,與列表一樣均為可變容器 1.通過大括號 將鍵值對 key...