Details of closure instances in Python, and details of python instances

Source: Internet
Author: User

Details of closure instances in Python, and details of python instances

In general, the concept of closure is involved in many languages. This article focuses on the definition and usage of closure in python. Closure in Python is mainly used for functional development. Detailed analysis is as follows:

I. Definition

Closures in python are defined (interpreted) in the form of representation as: If a variable in the external scope (but not in the global scope) is referenced in an internal function, therefore, internal functions are regarded as closures ). this definition is relatively straightforward and easy to understand. It is not as informative as other definitions (those with a strong learning taste, in the process of interpreting a term, it is filled with a bunch of other crazy unfamiliar terms, not suitable for beginners ). The following is a simple example.

>>>def addx(x): >>>  def adder(y): return x + y >>>  return adder >>> c = addx(8) >>> type(c) <type 'function'> >>> c.__name__ 'adder' >>> c(10) 18

Use this simple code and definition to describe the closure:
If in an internal function: adder (y) is the internal function,
Reference variables in the external scope (but not in the global scope): x is the referenced variable. x is in the external scope addx, but not in the global scope,
The internal function adder is a closure.

A slightly more important explanation is that the closure = function block + defines the function environment. The adder is the function block, and the x is the environment. Of course, there can be many such environments, more than one simple x.

Ii. Precautions for using closures

1. The closure cannot modify the local variables of the external scope.

>>> def foo(): ...   m = 0 ...   def foo1(): ...     m = 1 ...     print m ... ...   print m ...   foo1() ...   print m ...>>> foo()010

The execution result shows that although a variable m is defined in the closure, it does not change the local variable m in the external function.

2. The following code is a classic error code when using closures in python.

def foo():   a = 1   def bar():     a = a + 1     return a   return bar

This program is intended to Increment Variable a every time it calls the closure function. But in actual use

>>> c = foo() >>> print c() Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 4, in bar UnboundLocalError: local variable 'a' referenced before assignment 

This is because when executing code c = foo (), python imports all the closure function bodies bar () to analyze their local variables, the python rule specifies that all the variables on the left side of the value assignment statement are local variables. In the closure bar (), variable a is on the left side of the value assignment symbol "=" and is considered as bar () by python (). Next, when print c () is executed, when the program runs to a = a + 1, because a is previously classified as a local variable in bar (), python will () find the value of a on the right of the value assignment statement. If the result is not found, an error is returned. The solution is simple.

def foo():   a = [1]   def bar():     a[0] = a[0] + 1     return a[0]   return bar

You only need to set a as a container. This is a bit uncomfortable to use, so after python3, you can use the nonloacal a statement before a = a + 1, this statement explicitly specifies that a is not a local variable of the closure.

3. another example that is prone to errors is often mentioned when we introduce the python closure. I have never thought that this error has much to do with the closure, but it is indeed an easy mistake to make in python functional programming. I would like to introduce it here. Let's take a look at the following code.

for i in range(3):   print i

This type of loop statements often appears in the program. The problem with Python is that when the loop ends, the temporary variable I in the loop body will not be destroyed, but will continue to exist in the execution environment. Another python phenomenon is that python functions are only executed to find the variable values in the function body.

flist = [] for i in range(3):   def foo(x): print x + i   flist.append(foo) for f in flist:   f(2)

Some people may think that the execution result of this code should be 2, 3, 4, but the actual result is 4, 4. This is because when a function is added to the flist list, python has not assigned a value to I. Only when the function is executed, what is the value of I? After the first for loop ends, the value of I is 2, so the execution result of the above Code is 4, 4, 4.
The solution is also very simple. Just rewrite the definition of the function.

for i in range(3):   def foo(x,y=i): print x + y   flist.append(foo) 

Iii. Functions

After talking about this, someone may ask, what is the use of this closure in actual development? Closures are mainly used in functional development. The following describes the main uses of the two closures.

Purpose 1: After the closure is executed, it can still maintain the current running environment.

For example, if you want the result of each function execution, it is based on the result of the previous operation of the function. I will illustrate it with an example similar to a board game. Assume that the size of the Board is 50*50, and the upper left corner is the coordinate system origin (). I need a function that receives two parameters: direction (direction), step (step ), this function controls the movement of pawns. In addition to the direction and step size, the new coordinates of the pawnpiece movement depend on the coordinates of the pawnpiece. Of course, you must use the closure to maintain the coordinates of the pawnpiece.

Origin = [0, 0] # Coordinate System origin legal_x = [0, 50] # Legal coordinate legal_y in the X axis direction = [0, 0, 50] # valid coordinate def create (pos = origin) in the Y axis: def player (direction, step): # determine the legality of the direction and step parameter first, for example, direction cannot be skewed, and step cannot be negative. # Then, we need to judge and process the validity of the newly generated x and y coordinates. Here we mainly want to introduce the closure, it is not detailed. New_x = pos [0] + direction [0] * step new_y = pos [1] + direction [1] * step pos [0] = new_x pos [1] = new_y # Note! Pos = [new_x, new_y] cannot be written here. The reason is as follows: return pos return player = create () # create a chess player. the start point is print player ([1, 0], 10) # Move 10 print player ([], 20) to the positive side of the X axis # Move 20 print player ([-], 10) to the positive side of the Y axis) # Move 10 steps toward the negative direction of the X axis

Output:

[10, 0] [10, 20] [0, 20] 

Purpose 2: closures can get different results based on local variables in the external scope. This is a bit like a configuration function. We can modify the external variables, the closure shows different functions based on this variable. For example, if we need to analyze the special lines of some files, We need to extract these special lines first.

def make_filter(keep):   def the_filter(file_name):     file = open(file_name)     lines = file.readlines()     file.close()     filter_doc = [i for i in lines if keep in i]     return filter_doc   return the_filter

If we need to obtain the line containing the "pass" keyword in the file "result.txt", we can use the example program in this way.

filter = make_filter("pass")filter_result = filter("result.txt")

The above two use cases can be easily implemented using object-oriented programming. However, when using Python for functional programming, the closure will persist data and generate different functions according to configuration, is very helpful.

I believe this article provides some reference for everyone's Python program design.


How to pass an inner function to the outer layer in the python closure function?

Closures are not required to implement this function.

Def fun (callback, * x ):
Return callback (* x)

Python class instantiation

1. In a python class, a private variable or function starts with _ (two underscores) but does not end with _. Private functions and variables cannot be called out of class.
Class test:
Def _ init _ (self, num ):
Self. _ num = num
PrivateTest = test (100)
PrivateTest. _ num # An error is returned.
Of course, there is also a way to adjust it, but it is not recommended to do that.
2. The variable s in the first class se () is a class variable, which can be accessed by the class itself, such as se. s, can also be accessed by various objects, and the value is unique because it exists in the class, a bit like static in C ++.
However, if an object also creates a variable named s that overwrites the class variable, the self. s is the property of the object and will not be adjusted to the class variable.
You can run it.
#-*-Coding: cp936 -*-
Class:
Name = []
Def _ init _ (self, name ):
Self. name. append (name)

Def nameMyself (self, name ):
Self. name = [name]
Print 'My name is ', self. name,' and class A1name is: ', A. name

Def test (self ):
Print "my name is", self. name
Obj = A ("num0 ")
Obj1 = A ("num1 ")
Print "obj1 'name", obj1.name # object metadata class variable name
Print "class A 'name", A. name # class variable name
Obj1.test () # The name Of The accessed class variable.
Obj1.nameMyself ('aid ') # Give yourself a name that overwrites the name of the class variable
Obj1.test () # For obj1, you can only access your own name.
Print "class a' name", A. name # The class variable still exists.

Related Article

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.