SlideShare a Scribd company logo
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
Ad

More Related Content

What's hot (20)

Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
seanmcq
 
Python Async IO Horizon
Python Async IO HorizonPython Async IO Horizon
Python Async IO Horizon
Lukasz Dobrzanski
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
Jason 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 Reloaded
Roman 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
 
Rust
RustRust
Rust
Chih-Hsuan Kuo
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
Han 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-architecture
Jung Kim
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
Chih-Hsuan Kuo
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
Kirill 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 Kotlin
Andrey Breslav
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
Ayesh Karunaratne
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
Anton 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 kotlin
Ahmad Arif Faizin
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
Roman Elizarov
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
Brendan Eich
 
Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
seanmcq
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
Jason 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 Reloaded
Roman 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 Python
Han 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-architecture
Jung Kim
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
Chih-Hsuan Kuo
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
Kirill 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 Kotlin
Andrey Breslav
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
Ayesh Karunaratne
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
Anton 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 kotlin
Ahmad Arif Faizin
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
Roman Elizarov
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
Brendan Eich
 

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
Sté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 Programming
Paul Solt
 
Authoring tools worksheet
Authoring tools worksheetAuthoring tools worksheet
Authoring tools worksheet
Farid Diah
 
Cpu cycle
Cpu cycleCpu cycle
Cpu cycle
maciakl
 
Wk1to4
Wk1to4Wk1to4
Wk1to4
raymondmy08
 
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
Alexandre Moneger
 
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
Conferencias FIST
 
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
Paul Solt
 
Smashing The Stack
Smashing The StackSmashing The Stack
Smashing The Stack
Daniele Bellavista
 
Introduction to Linux Exploit Development
Introduction to Linux Exploit DevelopmentIntroduction to Linux Exploit Development
Introduction to Linux Exploit Development
johndegruyter
 
Exploit techniques and mitigation
Exploit techniques and mitigationExploit techniques and mitigation
Exploit techniques and mitigation
Yaniv 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 C
Uri Dekel
 
Addressing
Addressing Addressing
Addressing
souravmoy
 
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
securityxploded
 
Low Level Exploits
Low Level ExploitsLow Level Exploits
Low Level Exploits
hughpearse
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU Debugger
Priyank Kapadia
 
The Stack Frame
The Stack FrameThe Stack Frame
The Stack Frame
Ivo Marinkov
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
National Cheng Kung University
 
Advanced exploit development
Advanced exploit developmentAdvanced exploit development
Advanced exploit development
Dan H
 
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
Sté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 Programming
Paul Solt
 
Authoring tools worksheet
Authoring tools worksheetAuthoring tools worksheet
Authoring tools worksheet
Farid Diah
 
Cpu cycle
Cpu cycleCpu cycle
Cpu cycle
maciakl
 
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
Alexandre 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 Programming
Paul Solt
 
Introduction to Linux Exploit Development
Introduction to Linux Exploit DevelopmentIntroduction to Linux Exploit Development
Introduction to Linux Exploit Development
johndegruyter
 
Exploit techniques and mitigation
Exploit techniques and mitigationExploit techniques and mitigation
Exploit techniques and mitigation
Yaniv 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 C
Uri 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 Basics
securityxploded
 
Low Level Exploits
Low Level ExploitsLow Level Exploits
Low Level Exploits
hughpearse
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU Debugger
Priyank Kapadia
 
Advanced exploit development
Advanced exploit developmentAdvanced exploit development
Advanced exploit development
Dan H
 
Ad

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
Wiem Zine Elabidine
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
Daehee 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 Concerns
saintiss
 
User defined functions
User defined functionsUser defined functions
User defined functions
shubham_jangid
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivars
Leonardo Soto
 
Functions12
Functions12Functions12
Functions12
sandhubuta
 
Functions123
Functions123 Functions123
Functions123
sandhubuta
 
Python speleology
Python speleologyPython speleology
Python speleology
Andrés J. Díaz
 
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
akaptur
 
Android and cpp
Android and cppAndroid and cpp
Android and cpp
Joan Puig Sanz
 
functions
functionsfunctions
functions
Makwana Bhavesh
 
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
Michael 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-functions
ankita44
 
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, monads
rkaippully
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
PyCon Italia
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
rik0
 
New in php 7
New in php 7New in php 7
New in php 7
Vic Metcalfe
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard Tomàs
 
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
Wiem Zine Elabidine
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
Daehee 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 Concerns
saintiss
 
User defined functions
User defined functionsUser defined functions
User defined functions
shubham_jangid
 
Decent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivarsDecent exposure: Controladores sin @ivars
Decent exposure: Controladores sin @ivars
Leonardo 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 interpreter
akaptur
 
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
Michael 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-functions
ankita44
 
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, monads
rkaippully
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
rik0
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard Tomàs
 
Ad

Recently uploaded (20)

HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 

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