The following content is based on python3.4
1. How does the normal function in Python work?
When a Python function executes, it runs on the corresponding Python stack frame, which represents a frame in the function call stack when the program runs. To obtain a stack frame related to a function, it must be obtained when the function is called and the function has not yet returned, possibly through the currentframe () function of the inspect module to get the current stack frame.
3 Common properties in a stack frame object:
- F_back: The upper stack frame of the call stack
- F_code: Stack frame corresponding to C
- F_locals: Local variables used in the current stack frame;
Like what:
Import Inspect def func (): ... Global x ... =>>> x = None>>> func ()>>> x<frame object at 0x7f50f3ee2868>
Further, the standard Python interpreter is written in C, often called CPython, and when a Python function is executed, the C function Pyeval_evalframeex () in the interpreter is called, which handles the bytecode of the Python code, Its parameters are the stack frame object for the Python function, that is, the x in the example above is a stack frame.
For example, how does a function work?
def foo (): ... = ... = Bar () ... return def Bar () : ... return ' Hello ' ...
Use the DIS module to see the byte code of the function foo () (The content is OK, others are regular):
Import dis>>> dis.dis (foo) 2 0 load_const 1 (3) store_fast 0 (x) 3 6 load_global 0 (bar) 9 call_function 0 (0 positional, 0 keyword pair) store_fast 1 (y) 4 load_fast 1 (y )return_value
Run the process:
The interpreter calls the C function Pyeval_evalframeex () to run the bytecode of Foo (), its argument is foo () corresponding to the stack frame object, and the stack frame where the run position is foo (), and during the run, when it encounters Call_function, it will be the function bar () Generate a new stack frame, and then call a Pyeval_evalframeex () to run Bar () corresponding to the bytecode, ..., so recursive, then a layer of return;
2. For stack frames in Python:
The stack frame in Python is actually allocating memory on the interpreter's heap, so after a Python function is finished, its stack frame still exists and does not disappear, as shown in the following example (when the Func function is finished, we can then access its corresponding stack frame):
Import Inspect def func (): ... Global x ... =>>> x = None>>> func ()>>> x<frame object at 0x7f50f3ee2868>>>> x.f_code.co_name'func'
3. How does the builder function in Python work?
# This is a function def func (): ... Print ('you'reSB'# This is a generator
def Gen (): ... yield ' You are SB ' ... return ' ni gei wo gun '
The difference between a function and a generator function is that there are yield expressions in the generator, and their co_flags are not the same:
function without *args or **kw, func.__code__.co_flags=67; function has *args without **kw, func.__code__.co_flags=71;
function does not have **kw when *args, func.__code__.co_flags=75; function has both *args and **kw, func.__code__.co_flags=79;
function is a generator when func.__code__.co_flags=99.
>>> func. __code__ . co_flags67>>> gen__code__. Co_flags99
When you run a generator function, it generates a generator:
>>> a = gen ()>>> type (a)<class'generator' >>>> b= gen ()>>> b<generator object Gen at 0x7f50f4a7a3f0>
The above example generates two generators A and B, each generator has two commonly used properties, respectively Gi_frame and Gi_code, different generator gi_code is the same, corresponding to the generator function bytecode, but their gi_frame is not the same, so, Different generators can be run separately without interfering with each other;
For each stack frame there is also a pointer f_lasti, which points to the last command executed, at the beginning of no execution, its value is-1;
>>> a.gi_frame.f_lasti-1>>> a.send (None)'you'reSB' >>> a.gi_frame.f_lasti3>>> b.gi_frame.f_lasti-1
When the generator executes to the end, it produces an StopIteration
exception and then stops, and when there is a return in the generator function, the value of the exception is the value of return, and if there is no return, the value of the exception is null;
>>> Next (b)'you'reSB'>>> next (b) Traceback (most recent Call last): '<stdin>' in <module>stopiteration:ni GEi wo gun
This is how the generator function works.
Reference: A Web Crawler with Asyncio coroutines content:
How does the builder function in Python work?