SlideShare a Scribd company logo
1 of 88
Python yield
     Mail & Popo: yangjunwei@




     1
Agenda
•   why thinking in yield?

•   yield

•   yield

•   yield



                             2
why thinking in yield?



          3
why thinking in yield?

db.begin()
if check_error1_happen(db):
    db.rollback()
    return Response(“error1 happens”)

if check_error2_happen(db):
    db.rollback()
    return Response(“error2 happens”)

db.table.update()
....
db.commit()

return Response(“success”)


                          4
why thinking in yield?




•     pythonic


•   bug




                      5
why thinking in yield?
                                      @contextmanager
                                      def transaction(conn):
class Job(object):                      trans = Job()
   def __init__(self):                  conn.begin()
      self._finished = False
                                        try:
                                           yield trans
  def is_finished(self):                 except:
    return self._finished                   conn.rollback()
                                           raise

  def finish(self):                      if trans.is_finished():
    self._finished = True                    conn.commit()
                                        else:
                                            conn.rollback()

                                  6
why thinking in yield?


with transaction(db) as trans:
   if check_error1_happen(db):
       return Response(“error1 happens”)

   if check_error2_happen(db):
       return Response(“error2 happens”)

   db.table.update()
   ....
   trans.finish()

return Response(“success”)



                       7
why thinking in yield?

main                         main
           A                              yield function



       B       C




                         yield function


                         8
yield



        9
yield


Using a yield expression in a function definition is sufficient to
cause that definition to create a generator function instead of
a normal function.




                                  10
yield


Using a yield expression in a function definition is sufficient to
cause that definition to create a generator function instead of
a normal function.


   >>> def f():
   ... yield "hello world"
   ...
   >>> type(f())
   <type 'generator'>




                                  10
yield

That generator then controls the execution of a generator
function.




                              11
yield

That generator then controls the execution of a generator
function.


  •   send()

  •   next() ==> send(None)

  •   throw()

  •   close() ==> throw(GeneratorExit)


                              11
yield


yield is a expression, not a statement. New in python 2.5




                               12
yield


yield is a expression, not a statement. New in python 2.5

>>> def f():
... a = yield "hello"
... print a
...
>>> b = f()
>>> b.send(None)
'hello'
>>> b.send("world")
world
StopIteration

                               12
yield


generator is also a iterator.




                                13
yield


generator is also a iterator.



>>> a = f()
>>> a is a.__iter__()
True




                                13
yield

generator object




                       14
yield

generator object


>>> def f():
... yield "hello world"
...
>>> a = f()
>>> a.next()
“hello world”
>>> a.next()
StopIteration
>>> a.next()
StopIteration


                              14
yield



        15
yield
tstate_head

                    next                   next
    PyThreadState          PyThreadState          ...
   frame

   PyFrameObject

   f_back
   PyFrameObject

  f_back
                      python
            ...

                              16
yield

   code block
              compile
 PyCodeObject

              MAKE_FUNCTION
PyFunctionObject
              CALL_FUNCTION

 PyFrameObject



         17
yield
[frameobject.c]

typedef struct {
   ...
   struct _frame *f_back;
   PyCodeObject *f_code;
   PyObject *f_builtins;
   PyObject *f_globals;
   PyObject *f_locals;
   PyObject *f_valuestack;
   PyObject *f_stacktop;
   ...
   int f_lasti;
   ...
} PyFrameObject;

                             18
yield


[codeobject.c]

typedef struct {
   ...
   int co_flags;
   ...
   PyObject *co_code;
   PyObject *co_consts;
   PyObject *co_names;
   ...
} PyCodeObject;



                          19
yield


[a.py]                        [b.py]


def f():                      def f():
  return “hello world”          yield “hello world”

f()                           f()




         PyCodeObject <==> code block



                         20
yield



4   0 LOAD_CONST            0 (<code object f ..>)
    3 MAKE_FUNCTION         0
    6 STORE_NAME            0 (f)

7    9 LOAD_NAME            0 (f)
    12 CALL_FUNCTION        0
    15 POP_TOP
    16 LOAD_CONST           1 (None)
    19 RETURN_VALUE

             dis.dis(main_code)

                       21
yield


5   0 LOAD_CONST              1 ('hello world')
    3 RETURN_VALUE


5   0 LOAD_CONST              1 ('hello world')
    3 YIELD_VALUE
    4 POP_TOP
    5 LOAD_CONST              0 (None)
    8 RETURN_VALUE

            dis.dis(f_code)


                    22
yield




  return generator




        23
yield

[ceval.c] CALL_FUNCTION

f = PyFrame_New(tstate, co, globals, locals);
...
if (co->co_flags & CO_GENERATOR) {
    ...
    f->f_back = NULL;
    ...
    return PyGen_New(f);
}

retval = PyEval_EvalFrameEx(f,0);



                               24
yield

[frameobject.c]

PyFrame_New(PyThreadState *tstate,
PyCodeObject *code, PyObject *globals, PyObject *locals){
   ...
   PyFrameObject *back = tstate->frame;
   PyFrameObject *f;
   f = PyObject_GC_Resize(PyFrameObject, f, extras);
   ...
   f->f_code = code;
   ...
   f->f_back = back;
   f->f_tstate = tstate;
   return f;
}


                                     25
yield

[ceval.c]

PyObject *PyEval_EvalFrameEx(PyFrameObject *f,
  int throwflag){
  ...
  PyThreadState *tstate = PyThreadState_GET();
  tstate->frame = f;
  ...
  // exec opcode
  ...
  tstate->frame = f->f_back;
  return retval;
}

                             26
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...


                                       27
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
                          f_back
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
      A frame                          new frame
   f_back
      B frame

   f_back
            ...
                                 yield

                                       28
yield
[genobject.c]

static PyObject * gen_send_ex(PyGenObject *gen, PyObject *arg, int
exc) {
   PyFrameObject *f = gen->gi_frame;
   f->f_back = tstate->frame;
   ...
   
if (f->f_lasti == -1) {
       ....
   } else {
        result = arg ? arg : Py_None;

        Py_INCREF(result);

        *(f->f_stacktop++) = result;
   }
   ...
   result = PyEval_EvalFrameEx(f, exc);
}

                                  29
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
   A frame(caller)                     new frame
   f_back
  B frame(creator)

   f_back
            ...
                                   send

                                       30
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
   A frame(caller)                     new frame
   f_back
  B frame(creator)

   f_back
            ...
                                   send

                                       30
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
   A frame(caller)                     new frame
                          f_back
   f_back
  B frame(creator)

   f_back
            ...
                                   send

                                       30
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
   A frame(caller)                     new frame
                          f_back
   f_back
  B frame(creator)

   f_back
            ...
                                   send

                                       30
yield
tstate_head

                          next
    PyThreadState                ...
                  frame
   A frame(caller)                     new frame
                          f_back
   f_back
  B frame(creator)

   f_back
            ...
                                   send

                                       30
yield




resume frame




                 31
yield
[ceval.c]

PyObject *PyEval_EvalFrameEx(PyFrameObject *f,
  int throwflag){
  ...
  
next_instr = first_instr + f->f_lasti + 1;

 stack_pointer = f->f_stacktop;

 assert(stack_pointer != NULL);

 f->f_stacktop = NULL;
  ...
      case YIELD_VALUE:
         retval = POP();
         f->f_stacktop = stack_pointer;
         why = WHY_YIELD;
         goto fast_yield;
}

                                 32
yield




[genobject.c]

static PyObject *gen_throw(PyGenObject *gen,
PyObject *args){
   ...
   
PyErr_Restore(typ, val, tb);

 return gen_send_ex(gen, Py_None, 1);
}

                     throw


                           33
yield




def close(self):
  try:
      self.throw(GeneratorExit)
  except (GeneratorExit, StopIteration):
      pass
  else:
      raise RuntimeError("generator ignored GeneratorExit")
  # Other exceptions are not caught

                         close

                               34
yield



    35
•   xrange


•     with_statement“          ”


•   python Trampoline

•     generator    coroutine



                        36
xrange




         37
xrange


[rangeobject.c]

static PyObject *
rangeiter_next(rangeiterobject *r)
{

 if (r->index < r->len)

 
 return PyInt_FromLong(r->start + (r->index++) * r-
>step);

 return NULL;
}

                    xrange

                             38
xrange

def xrange(start, stop, step=1):
  i = start - step
  while True:
      i = i + step

     if i < stop:
          yield i
     else:
          return


                        yield


                                39
xrange

l = [x for x in xrange(10)]
g = (x * x for x in xrange(10))

           list           generator




                  40
xrange

l = [x for x in xrange(10)]
g = (x * x for x in xrange(10))

           list           generator




                  40
xrange

l = [x for x in xrange(10)]
g = (x * x for x in xrange(10))

           list            generator




def f():
    for x in xrange(10):
       yield x * x




                  40
with_statement“   ”




          41
“with_statement”




      with        with




             42
“with_statement”




           with        with


with EXPR as VAR:
   BLOCK




                  42
“with_statement”




           with        with


with EXPR as VAR:
   BLOCK




                  42
“with_statement”

mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
   try:
      VAR = value # Only if "as VAR" is present
      BLOCK
   except:
      exc = False
      if not exit(mgr, *sys.exc_info()):
          raise
finally:
     if exc:
          exit(mgr, None, None, None)


                                     43
“with_statement”
class Transaction(object):
    def __init__(self, db):
        self._db = db
        self._trans = Job()

  def __enter__(self):
      self._db.begin()
      return self._trans

  def __exit__(self, type, value, traceback):
      if type is not None:
           self._db.rollback()
      else:
           self._db.commit()

                    yield              transaction

                                44
“with_statement”
@contextmanager
def transaction(conn):
  trans = Job()
  conn.begin()

  try:
     yield trans
  except:
     conn.rollback()
     raise

  if trans.is_finished():
      conn.commit()
  else:
      conn.rollback()

                            45
“with_statement”
@contextmanager
def transaction(conn):
  trans = Job()
  conn.begin()

  try:
     yield trans
  except:
     conn.rollback()
     raise

  if trans.is_finished():
      conn.commit()
  else:
      conn.rollback()

                            45
python Trampoline




        46
python Trampoline



def f(n):
    if n < 2:
         return n
    else:
         return n + f(n - 1)

>>> f(999)
499500
>>> f(1000)
RuntimeError: maximum recursion depth exceeded



                               47
python Trampoline




sys.getrecursionlimit()

Return the current value of the recursion limit, the
maximum depth of the Python interpreter stack. This
limit prevents infinite recursion from causing an
overflow of the C stack and crashing Python. It can be
set by setrecursionlimit().




                           48
python Trampoline




        49
python Trampoline

         f(n)                               f(n)
                                  control
     f(n-1)                                 f(n-1)

     f(n-2)                  scheduler      f(n-2)
f_back
          ...                                ...

         f(1)                               f(1)




                        50
python Trampoline




•    let generator "call" other generator by yielding
    the generator they wish to invoke.

•    Any non-generator value yielded by a
    generator is returned to the generator that
    "called" the one yielding the value.




                         51
python Trampoline




def f(n):
  if n < 2:
      yield n
  else:
      yield n + (yield f(n-1))




                           52
python Trampoline

def trampoline(main):
  stack = []
  value = main
  while True:
      if type(value) is types.GeneratorType:
          stack.append(value)
          value = stack[-1].next()
      else:
          stack.pop()
          if stack:
              value = stack[-1].send(value)
          else:
              return value

                            53
generator        coroutine




            54
generator        coroutine




Coroutine(           )
"    "   "   "




                         55
generator         coroutine




Coroutine(                 )
"       "   "     "



    Python's generator functions are almost coroutines.




                               55
generator        coroutine




generator   coroutine




                        56
generator        coroutine




generator     coroutine


•   coroutine “call” coroutine

•   coroutine scheduler




                           56
generator        coroutine



coroutine-based Python networking library



•   Eventlet(http://eventlet.net/)

•   Gevent(http://www.gevent.org/)




                            57
Resources & References

•   python references: yield expression

•   python

•   PEP 342: Coroutines via Enhanced Generators

•   PEP 343: the with statement



                         58
Q&A



 59
Thanks!



          60

More Related Content

What's hot

Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the pointseanmcq
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 DevsJason Hanson
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)jeffz
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines ReloadedRoman Elizarov
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)jeffz
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)James Titcumb
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung Kim
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in GeckoChih-Hsuan Kuo
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKirill Rozov
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinAndrey Breslav
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021Ayesh Karunaratne
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistAnton Arhipov
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinAhmad Arif Faizin
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Roman Elizarov
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 

What's hot (20)

Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
 
Python Async IO Horizon
Python Async IO HorizonPython Async IO Horizon
Python Async IO Horizon
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
Rust
RustRust
Rust
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlin
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 

Viewers also liked

NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014
NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014
NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014Stéphane ESCANDELL
 
Numbers and Values in Objective-C and C Programming
Numbers and Values in Objective-C and C ProgrammingNumbers and Values in Objective-C and C Programming
Numbers and Values in Objective-C and C ProgrammingPaul Solt
 
Authoring tools worksheet
Authoring tools worksheetAuthoring tools worksheet
Authoring tools worksheetFarid Diah
 
Cpu cycle
Cpu cycleCpu cycle
Cpu cyclemaciakl
 
02 - Introduction to the cdecl ABI and the x86 stack
02 - Introduction to the cdecl ABI and the x86 stack02 - Introduction to the cdecl ABI and the x86 stack
02 - Introduction to the cdecl ABI and the x86 stackAlexandre Moneger
 
2장. Runtime Data Areas
2장. Runtime Data Areas2장. Runtime Data Areas
2장. Runtime Data Areas김 한도
 
Functions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingFunctions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingPaul Solt
 
Introduction to Linux Exploit Development
Introduction to Linux Exploit DevelopmentIntroduction to Linux Exploit Development
Introduction to Linux Exploit Developmentjohndegruyter
 
Exploit techniques and mitigation
Exploit techniques and mitigationExploit techniques and mitigation
Exploit techniques and mitigationYaniv Shani
 
Introduction to pointers and memory management in C
Introduction to pointers and memory management in CIntroduction to pointers and memory management in C
Introduction to pointers and memory management in CUri Dekel
 
Reversing & Malware Analysis Training Part 4 - Assembly Programming Basics
Reversing & Malware Analysis Training Part 4 - Assembly Programming BasicsReversing & Malware Analysis Training Part 4 - Assembly Programming Basics
Reversing & Malware Analysis Training Part 4 - Assembly Programming Basicssecurityxploded
 
Low Level Exploits
Low Level ExploitsLow Level Exploits
Low Level Exploitshughpearse
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerPriyank Kapadia
 
Advanced exploit development
Advanced exploit developmentAdvanced exploit development
Advanced exploit developmentDan H
 

Viewers also liked (20)

NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014
NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014
NodeJS & Socket IO on Microsoft Azure Cloud Web Sites - DWX 2014
 
Numbers and Values in Objective-C and C Programming
Numbers and Values in Objective-C and C ProgrammingNumbers and Values in Objective-C and C Programming
Numbers and Values in Objective-C and C Programming
 
Authoring tools worksheet
Authoring tools worksheetAuthoring tools worksheet
Authoring tools worksheet
 
Cpu cycle
Cpu cycleCpu cycle
Cpu cycle
 
Wk1to4
Wk1to4Wk1to4
Wk1to4
 
02 - Introduction to the cdecl ABI and the x86 stack
02 - Introduction to the cdecl ABI and the x86 stack02 - Introduction to the cdecl ABI and the x86 stack
02 - Introduction to the cdecl ABI and the x86 stack
 
2장. Runtime Data Areas
2장. Runtime Data Areas2장. Runtime Data Areas
2장. Runtime Data Areas
 
Stack Frame Protection
Stack Frame ProtectionStack Frame Protection
Stack Frame Protection
 
Functions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingFunctions in Objective-C and C Programming
Functions in Objective-C and C Programming
 
Smashing The Stack
Smashing The StackSmashing The Stack
Smashing The Stack
 
Introduction to Linux Exploit Development
Introduction to Linux Exploit DevelopmentIntroduction to Linux Exploit Development
Introduction to Linux Exploit Development
 
Exploit techniques and mitigation
Exploit techniques and mitigationExploit techniques and mitigation
Exploit techniques and mitigation
 
Introduction to pointers and memory management in C
Introduction to pointers and memory management in CIntroduction to pointers and memory management in C
Introduction to pointers and memory management in C
 
Addressing
Addressing Addressing
Addressing
 
Reversing & Malware Analysis Training Part 4 - Assembly Programming Basics
Reversing & Malware Analysis Training Part 4 - Assembly Programming BasicsReversing & Malware Analysis Training Part 4 - Assembly Programming Basics
Reversing & Malware Analysis Training Part 4 - Assembly Programming Basics
 
Low Level Exploits
Low Level ExploitsLow Level Exploits
Low Level Exploits
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU Debugger
 
The Stack Frame
The Stack FrameThe Stack Frame
The Stack Frame
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
 
Advanced exploit development
Advanced exploit developmentAdvanced exploit development
Advanced exploit development
 

Similar to Python Yield

ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutineDaehee Kim
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concernssaintiss
 
User defined functions
User defined functionsUser defined functions
User defined functionsshubham_jangid
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsLeonardo Soto
 
Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterakaptur
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python Chetan Giridhar
 
Part 3-functions
Part 3-functionsPart 3-functions
Part 3-functionsankita44
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monadsrkaippully
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchainedEduard Tomàs
 

Similar to Python Yield (20)

ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concerns
 
User defined functions
User defined functionsUser defined functions
User defined functions
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivars
 
Functions12
Functions12Functions12
Functions12
 
Functions123
Functions123 Functions123
Functions123
 
Python speleology
Python speleologyPython speleology
Python speleology
 
Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreter
 
Android and cpp
Android and cppAndroid and cpp
Android and cpp
 
functions
functionsfunctions
functions
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python
 
Part 3-functions
Part 3-functionsPart 3-functions
Part 3-functions
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 
New in php 7
New in php 7New in php 7
New in php 7
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 

Recently uploaded

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 

Recently uploaded (20)

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 

Python Yield

  • 1. Python yield Mail & Popo: yangjunwei@ 1
  • 2. Agenda • why thinking in yield? • yield • yield • yield 2
  • 3. why thinking in yield? 3
  • 4. why thinking in yield? db.begin() if check_error1_happen(db): db.rollback() return Response(“error1 happens”) if check_error2_happen(db): db.rollback() return Response(“error2 happens”) db.table.update() .... db.commit() return Response(“success”) 4
  • 5. why thinking in yield? • pythonic • bug 5
  • 6. why thinking in yield? @contextmanager def transaction(conn): class Job(object): trans = Job() def __init__(self): conn.begin() self._finished = False try: yield trans def is_finished(self): except: return self._finished conn.rollback() raise def finish(self): if trans.is_finished(): self._finished = True conn.commit() else: conn.rollback() 6
  • 7. why thinking in yield? with transaction(db) as trans: if check_error1_happen(db): return Response(“error1 happens”) if check_error2_happen(db): return Response(“error2 happens”) db.table.update() .... trans.finish() return Response(“success”) 7
  • 8. why thinking in yield? main main A yield function B C yield function 8
  • 9. yield 9
  • 10. yield Using a yield expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function. 10
  • 11. yield Using a yield expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function. >>> def f(): ... yield "hello world" ... >>> type(f()) <type 'generator'> 10
  • 12. yield That generator then controls the execution of a generator function. 11
  • 13. yield That generator then controls the execution of a generator function. • send() • next() ==> send(None) • throw() • close() ==> throw(GeneratorExit) 11
  • 14. yield yield is a expression, not a statement. New in python 2.5 12
  • 15. yield yield is a expression, not a statement. New in python 2.5 >>> def f(): ... a = yield "hello" ... print a ... >>> b = f() >>> b.send(None) 'hello' >>> b.send("world") world StopIteration 12
  • 16. yield generator is also a iterator. 13
  • 17. yield generator is also a iterator. >>> a = f() >>> a is a.__iter__() True 13
  • 19. yield generator object >>> def f(): ... yield "hello world" ... >>> a = f() >>> a.next() “hello world” >>> a.next() StopIteration >>> a.next() StopIteration 14
  • 20. yield 15
  • 21. yield tstate_head next next PyThreadState PyThreadState ... frame PyFrameObject f_back PyFrameObject f_back python ... 16
  • 22. yield code block compile PyCodeObject MAKE_FUNCTION PyFunctionObject CALL_FUNCTION PyFrameObject 17
  • 23. yield [frameobject.c] typedef struct { ... struct _frame *f_back; PyCodeObject *f_code; PyObject *f_builtins; PyObject *f_globals; PyObject *f_locals; PyObject *f_valuestack; PyObject *f_stacktop; ... int f_lasti; ... } PyFrameObject; 18
  • 24. yield [codeobject.c] typedef struct { ... int co_flags; ... PyObject *co_code; PyObject *co_consts; PyObject *co_names; ... } PyCodeObject; 19
  • 25. yield [a.py] [b.py] def f(): def f(): return “hello world” yield “hello world” f() f() PyCodeObject <==> code block 20
  • 26. yield 4 0 LOAD_CONST 0 (<code object f ..>) 3 MAKE_FUNCTION 0 6 STORE_NAME 0 (f) 7 9 LOAD_NAME 0 (f) 12 CALL_FUNCTION 0 15 POP_TOP 16 LOAD_CONST 1 (None) 19 RETURN_VALUE dis.dis(main_code) 21
  • 27. yield 5 0 LOAD_CONST 1 ('hello world') 3 RETURN_VALUE 5 0 LOAD_CONST 1 ('hello world') 3 YIELD_VALUE 4 POP_TOP 5 LOAD_CONST 0 (None) 8 RETURN_VALUE dis.dis(f_code) 22
  • 28. yield return generator 23
  • 29. yield [ceval.c] CALL_FUNCTION f = PyFrame_New(tstate, co, globals, locals); ... if (co->co_flags & CO_GENERATOR) { ... f->f_back = NULL; ... return PyGen_New(f); } retval = PyEval_EvalFrameEx(f,0); 24
  • 30. yield [frameobject.c] PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals){ ... PyFrameObject *back = tstate->frame; PyFrameObject *f; f = PyObject_GC_Resize(PyFrameObject, f, extras); ... f->f_code = code; ... f->f_back = back; f->f_tstate = tstate; return f; } 25
  • 31. yield [ceval.c] PyObject *PyEval_EvalFrameEx(PyFrameObject *f, int throwflag){ ... PyThreadState *tstate = PyThreadState_GET(); tstate->frame = f; ... // exec opcode ... tstate->frame = f->f_back; return retval; } 26
  • 32. yield tstate_head next PyThreadState ... frame A frame f_back B frame f_back ... 27
  • 33. yield tstate_head next PyThreadState ... frame A frame new frame f_back B frame f_back ... 27
  • 34. yield tstate_head next PyThreadState ... frame A frame new frame f_back B frame f_back ... 27
  • 35. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... 27
  • 36. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... 27
  • 37. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... 27
  • 38. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... 27
  • 39. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... 27
  • 40. yield tstate_head next PyThreadState ... frame A frame f_back B frame f_back ... yield 28
  • 41. yield tstate_head next PyThreadState ... frame A frame new frame f_back B frame f_back ... yield 28
  • 42. yield tstate_head next PyThreadState ... frame A frame new frame f_back B frame f_back ... yield 28
  • 43. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... yield 28
  • 44. yield tstate_head next PyThreadState ... frame A frame new frame f_back f_back B frame f_back ... yield 28
  • 45. yield tstate_head next PyThreadState ... frame A frame new frame f_back B frame f_back ... yield 28
  • 46. yield [genobject.c] static PyObject * gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) { PyFrameObject *f = gen->gi_frame; f->f_back = tstate->frame; ... if (f->f_lasti == -1) { .... } else { result = arg ? arg : Py_None; Py_INCREF(result); *(f->f_stacktop++) = result; } ... result = PyEval_EvalFrameEx(f, exc); } 29
  • 47. yield tstate_head next PyThreadState ... frame A frame(caller) new frame f_back B frame(creator) f_back ... send 30
  • 48. yield tstate_head next PyThreadState ... frame A frame(caller) new frame f_back B frame(creator) f_back ... send 30
  • 49. yield tstate_head next PyThreadState ... frame A frame(caller) new frame f_back f_back B frame(creator) f_back ... send 30
  • 50. yield tstate_head next PyThreadState ... frame A frame(caller) new frame f_back f_back B frame(creator) f_back ... send 30
  • 51. yield tstate_head next PyThreadState ... frame A frame(caller) new frame f_back f_back B frame(creator) f_back ... send 30
  • 53. yield [ceval.c] PyObject *PyEval_EvalFrameEx(PyFrameObject *f, int throwflag){ ... next_instr = first_instr + f->f_lasti + 1; stack_pointer = f->f_stacktop; assert(stack_pointer != NULL); f->f_stacktop = NULL; ... case YIELD_VALUE: retval = POP(); f->f_stacktop = stack_pointer; why = WHY_YIELD; goto fast_yield; } 32
  • 54. yield [genobject.c] static PyObject *gen_throw(PyGenObject *gen, PyObject *args){ ... PyErr_Restore(typ, val, tb); return gen_send_ex(gen, Py_None, 1); } throw 33
  • 55. yield def close(self): try: self.throw(GeneratorExit) except (GeneratorExit, StopIteration): pass else: raise RuntimeError("generator ignored GeneratorExit") # Other exceptions are not caught close 34
  • 56. yield 35
  • 57. xrange • with_statement“ ” • python Trampoline • generator coroutine 36
  • 58. xrange 37
  • 59. xrange [rangeobject.c] static PyObject * rangeiter_next(rangeiterobject *r) { if (r->index < r->len) return PyInt_FromLong(r->start + (r->index++) * r- >step); return NULL; } xrange 38
  • 60. xrange def xrange(start, stop, step=1): i = start - step while True: i = i + step if i < stop: yield i else: return yield 39
  • 61. xrange l = [x for x in xrange(10)] g = (x * x for x in xrange(10)) list generator 40
  • 62. xrange l = [x for x in xrange(10)] g = (x * x for x in xrange(10)) list generator 40
  • 63. xrange l = [x for x in xrange(10)] g = (x * x for x in xrange(10)) list generator def f(): for x in xrange(10): yield x * x 40
  • 65. “with_statement” with with 42
  • 66. “with_statement” with with with EXPR as VAR: BLOCK 42
  • 67. “with_statement” with with with EXPR as VAR: BLOCK 42
  • 68. “with_statement” mgr = (EXPR) exit = type(mgr).__exit__ # Not calling it yet value = type(mgr).__enter__(mgr) exc = True try: try: VAR = value # Only if "as VAR" is present BLOCK except: exc = False if not exit(mgr, *sys.exc_info()): raise finally: if exc: exit(mgr, None, None, None) 43
  • 69. “with_statement” class Transaction(object): def __init__(self, db): self._db = db self._trans = Job() def __enter__(self): self._db.begin() return self._trans def __exit__(self, type, value, traceback): if type is not None: self._db.rollback() else: self._db.commit() yield transaction 44
  • 70. “with_statement” @contextmanager def transaction(conn): trans = Job() conn.begin() try: yield trans except: conn.rollback() raise if trans.is_finished(): conn.commit() else: conn.rollback() 45
  • 71. “with_statement” @contextmanager def transaction(conn): trans = Job() conn.begin() try: yield trans except: conn.rollback() raise if trans.is_finished(): conn.commit() else: conn.rollback() 45
  • 73. python Trampoline def f(n): if n < 2: return n else: return n + f(n - 1) >>> f(999) 499500 >>> f(1000) RuntimeError: maximum recursion depth exceeded 47
  • 74. python Trampoline sys.getrecursionlimit() Return the current value of the recursion limit, the maximum depth of the Python interpreter stack. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python. It can be set by setrecursionlimit(). 48
  • 76. python Trampoline f(n) f(n) control f(n-1) f(n-1) f(n-2) scheduler f(n-2) f_back ... ... f(1) f(1) 50
  • 77. python Trampoline • let generator "call" other generator by yielding the generator they wish to invoke. • Any non-generator value yielded by a generator is returned to the generator that "called" the one yielding the value. 51
  • 78. python Trampoline def f(n): if n < 2: yield n else: yield n + (yield f(n-1)) 52
  • 79. python Trampoline def trampoline(main): stack = [] value = main while True: if type(value) is types.GeneratorType: stack.append(value) value = stack[-1].next() else: stack.pop() if stack: value = stack[-1].send(value) else: return value 53
  • 80. generator coroutine 54
  • 81. generator coroutine Coroutine( ) " " " " 55
  • 82. generator coroutine Coroutine( ) " " " " Python's generator functions are almost coroutines. 55
  • 83. generator coroutine generator coroutine 56
  • 84. generator coroutine generator coroutine • coroutine “call” coroutine • coroutine scheduler 56
  • 85. generator coroutine coroutine-based Python networking library • Eventlet(http://eventlet.net/) • Gevent(http://www.gevent.org/) 57
  • 86. Resources & References • python references: yield expression • python • PEP 342: Coroutines via Enhanced Generators • PEP 343: the with statement 58
  • 88. Thanks! 60

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n