This article focuses on the understanding of several advanced grammatical concepts: Anonymous functions, lambda expressions, closures, adorners.
These concepts are not python specific, but this article is limited to Python instructions.
1. Anonymous functions
Anonymous Functions (anonymous function)is a function that is not bound to any identifier, and is used in the Functional programming languages field, typical applications:
1) passed as a parameter to the higher order function (Higher-order function), such as the built-in function in PythonFilter/map/reduce are typical high-order functions.
2) as the return value of the higher order function (although the "value" here is actually a function object)
In contrast to a named function (named function), an anonymous function is syntactically more lightweight if it is called only 1 or a finite number of times.
on the specific syntax, Python supports the function body as an anonymous function of an expression through lambda syntax, namely:Python's lambda expression is essentially an anonymous function, but its function body can only be an expression and cannot contain other statements .
In addition, advanced dynamic languages often use anonymous functions to implement closures (closure) or adorners (decorator) and other advanced grammars.
in some cases, the use of lambda expressions makes Python programs look very concise. For example, here is an example code that sorts the DICT elements based on value:
>>> foo = {' father ': +, ' mother ': +, ' sister ': $, ' brother ': ' Me ': 28}>>> sorted (foo.iterite MS (), KEY=LAMBDA x:x[1]) [(' Me ', "), (' brother ',"), (' sister ', ' a '), (' Mother ', ' + '), (' father ', 65)]
2. Closures
Closures (Closure)essentially a function or function reference that contains its reference environment (referencing environment), where the "reference environment" is usually maintained by a table, theThe table stores a reference to the non-local variable (non-local variables) that the function accesses.
and the letter in the C languagea closure allows a nested function to access the non-local variable outside its scope, as opposed to the Python interpreter's scope lookup rules for variables (Python supports LEGB lookuprules, if you want to dig deeper, you can refer to <learning python> 4th edition, 17th chapter scopes about scopes and find rules, or view this articledo a quick understanding).
It is often difficult to support closures for languages where the runtime memory allocation model creates local variables on a linear stack (typically, for example, C). Because these languages are implemented in the underlying, if the function returns, the local variables defined in the function are destroyed as the function stack is recycled. However, closures require the non-local variable to be accessed on the underlying implementation to be executed in the closuretime to remain valid until the end of the life cycle of the closure, which is unexpectedly the non-local variables can only be destroyed if they are determined to no longer be used, and cannot be defined with these variablesfunction to return the destroy. As a result, languages that naturally support closures typically use garbage collection to manage memory, because the GC mechanism guarantees that variables are not The system destroys and reclaims its memory space .
specifically, closures are usually accompanied by function nesting definitions. In Python, for example, a simple closure example is as follows:
#!/bin/env python#-*-encoding:utf-8-*-def startat_v1 (x): def incrementby (y): return x + y print ' ID ( IncrementBy) =%s '% (ID (incrementby)) return incrementbydef startat_v2 (x): return lambda y:x + y if ' __main__ ' = = __NAME__: c1 = STARTAT_V1 (2) print ' type (c1) =%s, C1 (3) =%s '% (type (c1), C1 (3)) print ' ID (C1) =%s '% (ID (C1)) C8/>C2 = STARTAT_V2 (2) print ' type (C2) =%s, C2 (3) =%s '% (type (C2), C2 (3))
The results of the implementation are as follows:
ID (IncrementBy) =139730510519782type (C1) =<type ' function ', C1 (3) =5id (C1) =139730510519782type (C2) =<type ' function ';, C2 (3) =5
In the example above, both STARTAT_V1 and startat_v2 implement closures, where: V1 is implemented with nested definition functions, and V2 is implemented with lambda expression/anonymous functions.
we take V1 as an example to explain the closure:
1) The function STARTAT_V1 accepts 1 parameters, returns 1 function objects, and the behavior of this function object is implemented by a nested defined function IncrementBy.
2) for function IncrementBy, the variable x is the so-called non-local variable (because x is not a local variable defined by the function, or a global variable in the ordinary sense), IncrementBy implements the specific function behavior and returns.
3) The return value received by the C1 of the main entry is a function object, from the ID (incrementby) = = ID (c1), it can be concluded that the object C1 "pointing" to the function name IncrementBy "Point" is actually the same functional object.
4) benefit from Python support for closures, the object that C1 points to can access the non-local variable that is not within its function scope, compared to the object of the normal function, and this variable is provided by the incrementby of the outer wrapper function STARTAT_V1. Equivalent to the function object pointed to by the C1 has "memory" function for its outer wrapper function, when creating the closure by calling the outer wrapper function, the different entry parameters are maintained by the inner layer function as the reference environment.
5) when calling C1 (3), the passed parameters are combined with the parameters of the outer wrapper function that references the environment to obtain the final result.
The above step analysis illustrates the rationale behind a closure from creation to execution, and after understanding the case, the concept of closure should also be clear.
3. Decorative Device
Python supports adorner (decorator) syntax. The concept of adorners is obscure to beginners because it involves several concepts of functional programming (such as anonymous functions, closures ), which is why the anonymous function and the closure are introduced in this article first.
We refer to this article for the definition of adorners:
A decorator is a function of takes a function object as an argument, and returns a function object as a return value.
From this definition, the adorner is essentially just a function, which uses the syntax of the closure to modify the behavior of a function (also known as a decorated function), that is, decorator is actually a closure function, the function is decorated function name (this function name is actually a function object reference) as the argument, After modifying the behavior of the decorated function within the closure, a new function object is returned .
Special Note:decorator does not have to be in the form of a function, it can be any object that can be called, for example it can also appear in class form, see the example given in this article.
With the function adorner defined, the decorator syntax sugar is interpreted by the Python interpreter to execute the adorner function first, and then continue executing the remaining statements on the new function object returned by the adorner when the external call to the decorated function is made.
An example to analyze:
#!/bin/env python#-*-encoding:utf-8-*-def Wrapper (FN): def inner (n, m): n + = 1 print ' in inner:fn=%s, n=%s , m=%s '% (fn.__name__, N, m) return FN (n, m) + 6 //returns with return value int object return inner@wrapperdef foo (n, m):
print ' in foo:n=%s, m=%s '% (n, m) return n * mprint foo (2, 3)
In the above example, Foo declares its adorner to be wrapper through @wrapper syntax sugar, and in wrapper, a nested inner function is defined (the function's argument list must be consistent with the parameter list of the Decorated function foo). Adorner wrapper after modifying the behavior of Foo, return inner (note: Because the return value of inner is an int object, Wrpper eventually returns an int object).
When calling Foo (2, 3), the Python interpreter first calls wrapper to overwrite Foo and then returns an int object, and it is not difficult to speculate that the above code executes as follows:
In Inner:fn=foo, n=3, m=3in foo:n=3, M=3foo (2, 3) =15
Resources
1. wikipedia:anonymous function
2. Wikipedia:closure (computer programming)
3. Chapter of book:learning python-powerful object-oriented Programming, 4th edition
4. A Beginner ' s Guide to Python's namespaces, scope resolution, and the LEGB rule
5. Python Decorators
6. Understanding Python Decorators in the easy steps!
7. decorators i:introduction to Python decorators
============= EOF =================
A few advanced syntax concepts for python notes Python: lambda expressions && closures && Decorators