Home  >  Article  >  Backend Development  >  Examples of usage of closures in Python

Examples of usage of closures in Python

黄舟
黄舟Original
2017-10-02 19:43:431032browse

This article mainly introduces the relevant information on the use of closures in the Python basic tutorial. I hope that this article can help you. Friends in need can refer to

The basic Python tutorial. How to use closures

Preface:

Closure (closure) is an important grammatical structure in functional programming. Functional programming is a programming paradigm (and procedural programming and object-oriented programming are also programming paradigms). In process-oriented programming, we have seen functions; in object-oriented programming, we have seen objects. The fundamental purpose of functions and objects is to organize code in a certain logical way and improve the reusability of the code. Closure is also a structure for organizing code, which also improves the reusability of code.

Different languages ​​implement closures in different ways. Python is based on function objects and provides support for the syntax structure of closures (we have seen many times that Python uses objects to implement some special syntax in special methods and multi-paradigms). Everything in Python is an object, and the grammatical structure of function is also an object. In a function object, we use the function object like a normal object, such as changing the name of the function object, or passing the function object as a parameter.

The scope of function objects

Like other objects, function objects also have their own scope of survival, which is the scope of the function object. Function objects are defined using def statements, and the scope of the function object is the same as the level at which def is located. For example, in the following code, the function line we define within the affiliation range of line_conf function can only be called within the affiliation range of line_conf.


def line_conf():
  def line(x):
    return 2*x+1
  print(line(5))  # within the scope


line_conf()
print(line(5))    # out of the scope

The line function defines a straight line (y = 2x + 1). It can be seen that the line function can be called in line_conf(), but calling line outside the scope will cause the following error:


NameError: name 'line' is not defined

means that it is already in outside the scope.

Similarly, if you use lambda to define a function, the scope of the function object is the same as the level where the lambda is located.

Closure

The function is an object, so it can be used as the return result of a certain function.


def line_conf():
  def line(x):
    return 2*x+1
  return line    # return a function object

my_line = line_conf()
print(my_line(5))

The above code can be run successfully. The return result of line_conf is assigned to the line object. The above code will print 11.

What happens if external variables are referenced in the definition of line()?


def line_conf():
  b = 15
  def line(x):
    return 2*x+b
  return line    # return a function object

b = 5
my_line = line_conf()
print(my_line(5))

We can see that the high-level variable b is referenced in the subordinate program block defined by line, but the b information exists outside the definition of line (the definition of b not in the line's subordinate block). We call b the environment variable of line. In fact, when line is used as the return value of line_conf, line already includes the value of b (although b is not affiliated with line).

The above code will print 25, that is to say, the b value referenced by line is the b value that can be referenced when the function object is defined, not the b value when used.

A function and its environment variables together form a

closure. In Python, the so-called closure is a function object that contains the value of an environment variable. Environment variable values ​​are stored in the __closure__ attribute of the function object. For example, the following code:


def line_conf():
  b = 15
  def line(x):
    return 2*x+b
  return line    # return a function object

b = 5
my_line = line_conf()
print(my_line.__closure__)
print(my_line.__closure__[0].cell_contents)

__closure__ contains a tuple. Each element in this tuple is an object of type cell. We see that the first cell contains the integer 15, which is the value of the environment variable b when we created the closure.

Let’s look at a practical example of closure:


def line_conf(a, b):
  def line(x):
    return ax + b
  return line

line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))

In this example, the function line and the environment variables a and b form a closure. When creating the closure, we specify the values ​​of these two environment variables through the parameters a and b of line_conf. In this way, we determine the final form of the function (y = x + 1 and y = 4x + 5). We only need to transform the parameters a and b to obtain different straight line expression functions. From this, we can see that closures also have the effect of improving code reusability.

If there is no closure, we need to specify a, b, x every time we create a straight line function. In this way, we need to pass more parameters and reduce the portability of the code. With closures, we actually create functionals. The line function defines a function in a broad sense. Some aspects of this function are already determined (it must be a straight line), but other aspects (such as the a and b parameters are undetermined). Subsequently, we determine the final function in the form of a closure based on the parameters passed by line_conf.

Closures and parallel operations

Closures effectively reduce the number of parameters that a function needs to define. This has important implications for parallel operations. In a parallel computing environment, we can make each computer responsible for a function, and then concatenate the output of one computer with the input of the next computer. Ultimately, we work like an assembly line, with data input from one end of a series of computer clusters and data output from the other end. This situation is best suited for functions with only one parameter input. Closures can achieve this purpose.

Parallel computing is becoming a hot spot. This is also an important reason why functional programming is becoming popular again. Functional programming has existed as early as the 1950s, but it was not widely used. However, the pipelined work-parallel clustering process we described above is perfectly suited to functional programming. Due to the natural advantages of functional programming, more and more languages ​​have begun to add support for the functional programming paradigm.

The above is the detailed content of Examples of usage of closures in Python. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn