Analysis of several advanced syntax concepts in Python (lambda expression closure decorator)

Source: Internet
Author: User
This article mainly records my understanding of several advanced syntax concepts: Anonymous functions, lambda expressions, closures, and decorators. These concepts are not specific to Python, but this article only describes them using Python. 1. anonymous functions
Anonymous function is a function that is not bound to any identifier. it is used in the functional programming ages field. Typical applications:
1) passed as a parameter to the high-order function (higher-order function). For example, the built-in function filter/map/reduce in python is a typical high-order function.
2) as the return value of the higher-order function (although the "value" here is actually a function object)
Compared with the named function, an anonymous function is more lightweight in syntax if it is called only once or for a limited number of times.
Specifically, python uses lambda syntax to support anonymous functions whose function bodies are expressions. that is, python lambda expressions are essentially anonymous functions, but their function bodies can only be expressions, it cannot contain other statements.
In addition, advanced dynamic languages often use anonymous functions to implement closure, decorator, and other advanced syntaxes.
In some cases, the use of lambda expressions makes the python program look very concise. For example, the following is a sample code that sorts dict elements by value:

>>> foo = {'father' : 65, 'mother' : 62, 'sister' : 38, 'brother' : 29, 'me' : 28}>>> sorted(foo.iteritems(), key=lambda x: x[1])[('me', 28), ('brother', 29), ('sister', 38), ('mother', 62), ('father', 65)]

2. closure
Closure is essentially a function or function reference that contains the referencing environment. here, the "reference environment" is usually maintained by a table, this table stores references to non-local variables accessed by the function.
Compared with function pointers in C, closures allow nested functions to access non-local variables out of their scope, this is related to the scope search rules of the Python interpreter for variables (Python supports the LEGB search rules. For more information, see For more information about the scope and search rules of Scopes, see the article ).
For languages where the runtime memory allocation model creates local variables on a linear stack (such as C), it is usually difficult to support closures. In the underlying implementation of these languages, if the function returns, the local variables defined in the function will be destroyed as the function stack is recycled. However, at the underlying implementation level, the closure requires that the non-local variable to be accessed be valid when the closure is executed until the lifecycle of the closure ends, this means that these non-local variables can be destroyed only when they are determined not to be used, and they cannot be destroyed as the function defining these variables returns. Therefore, languages that naturally support closures usually use garbage collection to manage memory, because the gc mechanism ensures that variables will be destroyed by the system and their memory space will be reclaimed only when they are no longer referenced.
In specific syntax, closures are usually accompanied by nested function definitions. Taking Python as an 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 incrementBy def 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))   c2 = startAt_v2(2) print 'type(c2)=%s, c2(3)=%s' % (type(c2), c2(3))

The execution result is as follows:

id(incrementBy)=139730510519782type(c1)=
 
  , c1(3)=5id(c1)=139730510519782type(c2)=
  
   , c2(3)=5
  
 

In the above example, startAt_v1 and startAt_v2 both implement closures, where v1 is implemented by nested definition functions; v2 is implemented by lambda expressions/anonymous functions.
Take v1 as an example to describe the closure:
1) the startAt_v1 function accepts one parameter and returns one function object. the behavior of this function object is implemented by the nested defined function incrementBy.
2) for the function incrementBy, variable x is the so-called non-local variable (because x is neither a local variable defined by the function nor a global variable in the general sense ), incrementBy implements specific function behavior and returns it.
3) The return value received by c1 in the main entry is a function object, which can be determined by id (incrementBy) = id (c1, c1 "points to" and the function name incrementBy "points to" is actually the same function object.
4) benefiting from Python's support for closures, compared with objects in common functions, c1 points to an object that can access non-local variables not in its function scope, this variable is provided by the input parameter of startAt_v1, the outer packaging function of incrementBy. Therefore, it is equivalent to the function object indicated by c1 that has the "memory" function for the input parameter of its outer packaging function, different input parameters are maintained by the inner function as the reference environment when an external function is called to create a closure.
5) When c1 (3) is called, the input parameters are calculated together with the parameters of the outer packaging function maintained by the reference environment to obtain the final result.
The above analysis shows the basic principle of a closure from creation to execution. after understanding this case, the concept of the closure should be clear.

3. decorator
Python supports the decorator syntax. The decorator concept is obscure for beginners, because it involves several functional programming concepts (such as anonymous functions and closures). This is why this article first introduces anonymous functions and closures.

We reference the definition of the decorator in this article:
A decorator is a function that takes a function object as an argument, and returns a function object as a return value.
According to this definition, the decorator is essentially a function. it uses the closure syntax to modify the behavior of a function (also called a decorated function). That is, the decorator is actually a closure function, this function uses the decorated function name (which is actually a reference to a function object) as an input parameter. after modifying the behavior of the decorated function in the closure, returns a new function object.
Note: decorator does not have to appear in the form of a function. it can be any object that can be called. for example, it can also appear in the form of a class. See the example in this article.
When the decorator function is called externally, the syntactic sugar of the decorator is interpreted by the Python interpreter as the decorator function, then execute other statements on the new function object returned by the decorator.
Analyze the following example:

#! /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 // return and return value: int object return inner @ wrapperdef foo (n, m ): print 'in foo: n = % s, m = % s' % (n, m) return n * m print foo (2, 3)

In the preceding example, foo declares through @ wrapper syntax that its modifier is wrapper. In wrapper, the nested inner function is defined (the parameter list of this function must be consistent with the parameter list of the decorated function foo). after the decorator wrapper modifies the behavior of foo, the inner is returned (note: since the inner return value is an int object, wrpper eventually returns an int object ).
When foo (2, 3) is called, the Python interpreter first calls wrapper to rewrite the behavior of foo and then returns the int object. it is not hard to guess that the execution result of the above code is as follows:

in inner: fn=foo, n=3, m=3in foo: n=3, m=3foo(2, 3)=15

For more information about several advanced syntax concepts in Python (lambda expression closure decorator), see The PHP Chinese website!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.