>å£çµæç»çæåï¼å°±æ¯ä»ç±ãåä¹ãåå¹³ãå¿èãæ©æ
ãè¯åãä¿¡å®ã温æãèå¶ãè¿æ ·çäºï¼æ²¡æå¾æ³ç¦æ¢ãå¡å±åºç£è¶ç¨£çäººï¼æ¯å·²ç»æèä½è¿èä½çéªæ
ç§æ¬²åéå¨ååæ¶ä¸äºãæä»¬è¥æ¯é å£çµå¾çï¼å°±å½é å£çµè¡äºãä¸è¦è´ªå¾èåï¼å½¼æ¤æ¹æ°ï¼äºç¸å«å¦ã(GALATIANS 5:22-26)
#çæå¨
ä¸èä¸ï¼æä»¬æ¾ç»åè¿è¿æ ·çæä½ï¼
>>> my_tup = (x**x for x in range(4))
>>> my_tup
at 0x02B7C2B0>
generatorï¼ç¿»è¯è¿æ¥æ¯çæå¨ã
çæå¨æ¯ä¸ä¸ªé常迷人çä¸è¥¿ï¼ä¹å¸¸è¢«è®¤ä¸ºæ¯Pythonçé«çº§ç¼ç¨æè½ãä¸è¿ï¼æä¾ç¶å¾ä¹æå¨è¿éè·è¯»è
ââå°½ç®¡ä½ å¯è½æ¯ä¸ä¸ªåå¦è
ââæ¢è®¨è¿ä¸ªè¯é¢ï¼å 为æç¸ä¿¡è¯»è
çæ¬æç¨çç®çï¼ç»éä»
ä»
å°èªå·±éå¶äºåå¦è
æ°´å¹³ï¼ä¸å®æä¸é¢ä¸ç¾çå¿ââè¦æä¸ºPython髿ãé£ä¹ï¼å¼å§äºè§£çæå¨å§ã
æ¢ç¶å¨æ¢è®¨âè¿ä»£å¨âçæ¶ååºç°äºçæå¨ï¼è¿å°±è¯´æçæå¨åè¿ä»£å¨æçä¸å®çæ¸æºå
³ç³»ã
没éï¼çæå¨å¿
é¡»æ¯å¯è¿ä»£çï¼å®é¦å
æ¯è¿ä»£å¨ã
ä½ï¼å®æ¯ç«è¿æ¯çæå¨ï¼å
·æçæå¨çç¹è´¨ã
##å®ä¹çæå¨
å®ä¹çæå¨ï¼å¿
须使ç¨`yield`å
³é®è¯ãyieldè¿ä¸ªè¯å¨æ±è¯ä¸æâç产ãåºäº§â乿ï¼å¨Pythonä¸ï¼å®ä½ä¸ºä¸ä¸ªå
³é®è¯ï¼æ¯çæå¨çæ å¿ã
>>> def g():
... yield 0
... yield 1
... yield 2
>>> g
建ç«äºä¸ä¸ªé常ç®åç彿°ï¼é颿`yield`åèµ·çä¸ä¸ªè¯å¥ãä¸é¢çå¦ä½ä½¿ç¨å®ï¼
>>> ge = g()
>>> ge
>>> type(ge)
è°ç¨å½æ°ï¼å¾å°äºä¸ä¸ªçæå¨(generator)对象ã
Python 2:
>>> dir(ge)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
Python 3:
>>> dir(ge)
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
å¨è¿éçå°äº`__iter__()`å`next()`æ`__next__()`ï¼è½ç¶æä»¬å¨å½æ°ä½å
å¹¶æ²¡ææ¾ç¤ºå°ååº`__iter__()`ã`next()`å`__next__()`ï¼ä»
ä»
åäº`yield`è¯å¥ï¼å®å°±å·²ç»æä¸ºè¿ä»£å¨äºã
æ¢ç¶å¦æ¤ï¼å½ç¶å¯ä»¥ï¼
>>> ge.next() #Python 3: ge.__next__()ï¼ä¸åï¼ä»ç¥
0
>>> ge.next()
1
>>> ge.next()
2
>>> ge.next()
Traceback (most recent call last):
File "", line 1, in
StopIteration
ä»è¿ä¸ªç®åä¾åä¸å¯ä»¥çåºï¼é£ä¸ªå«æ`yield`å
³é®è¯ç彿°æ¯ä¸ä¸ªçæå¨å¯¹è±¡ï¼è¿ä¸ªçæå¨å¯¹è±¡ä¹æ¯è¿ä»£å¨ã
äºæ¯å¯ä»¥è¿æ ·å®ä¹ï¼æå«æ`yield`è¯å¥ç彿°ç§°ä½çæå¨ã
çæå¨æ¯ä¸ç§ç¨æ®é彿°è¯æ³å®ä¹çè¿ä»£å¨ã
éè¿ä¸é¢çä¾åå¯ä»¥çåºï¼è¿ä¸ªçæå¨ï¼ä¹æ¯è¿ä»£å¨ï¼ï¼å¨å®ä¹è¿ç¨ä¸å¹¶æ²¡æåä¸èè¿ä»£å¨é£æ ·å`__iter__()`å`next()`ï¼èæ¯åªè¦ç¨äºyieldè¯å¥ï¼é£ä¸ªæ®é彿°å°±ç¥å¥è¬å°æä¸ºäºçæå¨ï¼ä¹å°±å
·å¤äºè¿ä»£å¨çåè½ç¹æ§ã
`yield`è¯å¥çä½ç¨ï¼å°±æ¯å¨è°ç¨çæ¶åè¿åç¸åºçå¼ã详ç»åæä¸ä¸ä¸é¢çè¿è¡è¿ç¨ï¼
1. `ge = g()`ï¼è¿åçæå¨ä¹å¤ã
2. `ge.next()`ï¼çæå¨æå¼å§æ§è¡ï¼éå°äºç¬¬ä¸ä¸ªyieldè¯å¥ï¼å°å¼è¿åï¼å¹¶æåæ§è¡ï¼æçç§°ä¹ä¸ºæèµ·ï¼ã
3. `ge.next()`ï¼ä»ä¸æ¬¡æåçä½ç½®å¼å§ï¼ç»§ç»å䏿§è¡ï¼éå°yieldè¯å¥ï¼å°å¼è¿åï¼åæåã
4. `gen.next()`ï¼éå¤ä¸é¢çæä½ã
5. `gene.next()`ï¼ä»ä¸é¢çæèµ·ä½ç½®å¼å§ï¼ä½æ¯å颿²¡æå¯æ§è¡çäºï¼äºæ¯`next()`ååºå¼å¸¸ã
ä»ä¸é¢çæ§è¡è¿ç¨ä¸ï¼åç°yieldé¤äºä½ä¸ºçæå¨çæ å¿ä¹å¤ï¼è¿æä¸ä¸ªåè½å°±æ¯è¿åå¼ãé£ä¹å®è·returnè¿ä¸ªè¿å弿ä»ä¹åºå«å¢ï¼
##yield
彿°è¿åå¼ï¼æ¬æ¥å·²ç»æäºä¸ä¸ª`return`ï¼ç°å¨ååºç°äº`yield`ï¼è¿ä¸¤ä¸ªæä»ä¹åºå«ï¼
为äºåºå«ï¼æä»¬å两个没æä»ä¹ç¨éç彿°ï¼
>>> def r_return(n):
... print "You taked me." #Python 3: print("You taked me.")ï¼ä¸åï¼ä»ç¥
... while n > 0:
... print "before return"
... return n
... n -= 1
... print "after return"
...
>>> rr = r_return(3)
You taked me.
before return
>>> rr
3
ä»å½æ°è¢«è°ç¨çè¿ç¨å¯ä»¥æ¸
æ°çåºï¼`rr = r_return(3)`ï¼å½æ°ä½å
çè¯å¥å°±å¼å§æ§è¡äºï¼éå°`return`ï¼å°å¼è¿åï¼ç¶åå°±ç»æå½æ°ä½å
çæ§è¡ãæä»¥`return`åé¢çè¯å¥æ ¹æ¬æ²¡ææ§è¡ãè¿æ¯`return`çç¹ç¹ï¼å
³äºæ¤ç¹ç¹ç详ç»è¯´æè¯·é
读[ã彿°(2)ãä¸çè¿åå¼ç¸å
³å
容](./202.md)ã
ä¸é¢å°returnæ¹ä¸ºyieldï¼
>>> def y_yield(n):
... print "You taked me." #Python 3: print("You taked me.")ï¼ä¸åï¼ä»ç¥
... while n > 0:
... print "before yield"
... yield n
... n -= 1
... print "after yield"
...
>>> yy = y_yield(3) #æ²¡ææ§è¡å½æ°ä½å
è¯å¥
>>> yy.next() #Python 3: yy.__next__()ï¼ä¸åï¼ä»ç¥
You taked me.
before yield
3 #éå°yieldï¼è¿åå¼ï¼å¹¶æå
>>> yy.next() #ä»ä¸æ¬¡æåä½ç½®å¼å§ç»§ç»æ§è¡
after yield
before yield
2 #åéå°yieldï¼è¿åå¼ï¼å¹¶æå
>>> yy.next() #éå¤ä¸è¿°è¿ç¨
after yield
before yield
1
>>> yy.next()
after yield #æ²¡ææ»¡è¶³æ¡ä»¶çå¼ï¼æåºå¼å¸¸
Traceback (most recent call last):
File "", line 1, in
StopIteration
ç»å注éååé¢å¯¹æ§è¡è¿ç¨çåæï¼è¯»è
ä¸å®è½çè§£`yield`çç¹ç¹äºï¼ä¹æ·±ç¥ä¸`return`çåºå«äºã
ä¸è¬ç彿°ï¼é½æ¯æ¢äº`return`ãä½ä¸ºçæå¨ç彿°ï¼ç±äºæäº`yield`ï¼åä¼éå°å®æèµ·ã
ææ³¢é£å¥æ°åå·²ç»æ¯èç¸è¯äºãä¸è®ºæ¯å¾ªç¯ãè¿ä»£é½ç¨å®ä¸¾ä¾è¿ï¼ç°å¨è®©æä»¬è¿ç¨å®å§ï¼åªä¸è¿æ¯è¦ç¨ä¸`yield`ã
#!/usr/bin/env python
# coding=utf-8
def fibs(max):
"""
ææ³¢é£å¥æ°åççæå¨
"""
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
if __name__ == "__main__":
f = fibs(10)
for i in f:
print i , #Python 3: print(i, end=',')
è¿è¡ç»æå¦ä¸ï¼
$ python 21501.py
1 1 2 3 5 8 13 21 34 55
ç¨çæå¨æ¹å¼å®ç°çææ³¢é£å¥æ°åæ¯ä¸æ¯è·ä»¥åçææä¸åäºå¢ï¼è¯»è
å¯ä»¥å°æ¬ä¹¦ä¸å·²ç»æ¼ç¤ºè¿çææ³¢é£å¥æ°åå®ç°æ¹å¼åä¸ä¸å¯¹æ¯ï¼ä½ä¼åç§æ¹æ³çå·®å¼ã
ç»è¿ä¸é¢çåç§ä¾åï¼å·²ç»æç¡®ï¼ä¸ä¸ªå½æ°ä¸ï¼åªè¦å
å«äº`yield`è¯å¥ï¼å®å°±æ¯çæå¨ï¼ä¹æ¯è¿ä»£å¨ãè¿ç§æ¹å¼æ¾ç¶æ¯åé¢åè¿ä»£å¨çç±»è¦ç®ä¾¿å¤äºãä½ï¼å¹¶ä¸æå³çä¸èç就被æå¼ãæ¯çæå¨è¿æ¯è¿ä»£å¨ï¼é½æ¯æ ¹æ®å
·ä½çä½¿ç¨æ
æ¯èå®ã
æåä¸å¥ï¼ä½ å¨ç¼ç¨ä¸ï¼ä¸ç¨çæå¨ä¹å¯ä»¥ã
------
[æ»ç®å½](./index.md) | [ä¸èï¼è¿ä»£å¨](./214.md) | [ä¸èï¼ä¸ä¸æç®¡çå¨](./235.md)
å¦æä½ è®¤ä¸ºæå¿
è¦æèµæï¼è¯·éè¿æ¯ä»å®ï¼**[email protected]**,ä¸èææ¿ã