[Notes] python Advanced Closure

[Notes] python Advanced Closure

table of Contents

1. issues into

2. What is a closure? (Focus)

3. Modify the external function variables


First by addressing a question to the introduction of the closure, and then to interpret and execute the closure process analysis.

1. issues into

In an example y = kx + b, calculate a line to a plurality of points i.e. x value y value is calculated.

# 问题:初中里学过函数,例如 y=kx+b, y=ax^2 + bx + c

# 以y=kx+b为例,请计算一条线上的多个点 即 给x值 计算出y值

# 第1种
# k = 1
# b = 2
# y = k*x+b
# 缺点:如果需要多次计算,那么就的写多次y = k*x+b这样的式子,不能重用

# 第2种:定义一个函数
def line_2(k, b, x):
	print(k*x+b)

line_2(1, 2, 0)
line_2(1, 2, 1)
line_2(1, 2, 2)
# 缺点:如果想要计算多次这条线上的y值,那么每次都需要传递k,b的值,麻烦

print("-"*50)


# 第3种: 全局变量,
k = 1
b = 2
def line_3(x):
	print(k*x+b)

line_3(0)
line_3(1)
line_3(2)
k = 11
b = 22
line_3(0)
line_3(1)
line_3(2)
# 缺点:如果要计算多条线上的y值,那么需要每次对全局变量进行修改,代码会增多,麻烦

print("-"*50)

# 第4种:缺省参数(注意,缺省参数放在后面)
def line_4(x, k=1, b=2):
	print(k*x+b)

line_4(0)
line_4(1)
line_4(2)

line_4(0, k=11, b=22)
line_4(1, k=11, b=22)
line_4(2, k=11, b=22)
# 优点:比全局变量的方式好在:k, b是函数line_4的一部分 而不是全局变量,因为全局变量可以任意的被其他函数所修改
# 缺点:如果要计算多条线上的y值,那么需要在调用的时候进行传递参数,麻烦

print("-"*50)

# 第5种:实例对象
# 创建实例对象的时候设置好k和b
class Line5(object):
	def __init__(self, k, b):
		self.k = k
		self.b = b

	def __call__(self, x):  # __call__方法,对象后面加括号,触发执行
		print(self.k * x + self.b)


line_5_1 = Line5(1, 2)
# 对象.方法()
# 对象():会触发__call__方法
line_5_1(0)  # 该形式即 对象() ,会调用__call__ 
line_5_1(1)
line_5_1(2)
line_5_2 = Line5(11, 22)
line_5_2(0)
line_5_2(1)
line_5_2(2)
# 缺点:为了计算多条线上的y值,所以需要保存多个k, b的值,因此用了很多个实例对象, 浪费资源

print("-"*50)

# 第6种:闭包

def line_6(k, b):
	def create_y(x):
		print(k*x+b)
	return create_y

line_6_1 = line_6(1, 2)  # 
line_6_1(0)
line_6_1(1)
line_6_1(2)
line_6_2 = line_6(11, 22)
line_6_2(0)
line_6_2(1)
line_6_2(2)

In the sixth, the closure of Solution:

Function create_y variable k, b constitute closures. In the creation of closure, we pass the parameter k line_6, b shows the values of these two variables. This determines the final form (y = kx + b) function. We only need to change the parameters k, b, you can get a different expression of linear function. It is seen, the closure also has a role to improve the reusability of code. If there is no closure, it is necessary to create each time the time when the linear function described k, b, x. For more parameter passing, reducing the portability of the code.

(Note: Due to the closures cited local variable external function, the local variable is not released in an external function, consume memory)

 

Thoughts: functions, anonymous functions, closures, objects do when the argument , what is the difference?

  1. Anonymous functions can perform basic functions simple, this is a passing reference to the function only functions (Note: the anonymous function created by the lambda keyword, followed by a colon and expressions have only one);
  2. Ordinary function to complete more complex functions, is transmitting the reference function only function;
  3. Closures to complete more complex features, is transmitted to the closure functions and data , thus the data transfer is the function + (simpler);
  4. Object to complete the most complex functions, it is transmitting a lot of data many features + (number of properties and methods can be used), and therefore the data transmission is the function +;

 

2. What is a closure? (Focus)

In the internal function then define a function (function multilayer nested definitions) , and this function uses a function of outside variables, then this function is used, and some variables called closure.

# 定义一个函数
def test(number):

    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数, number_in is %d" % number_in)
        return number+number_in
    # 其实这里返回的就是闭包的结果
    return test_in


# 给test函数赋值,这个20就是给参数number
ret = test(20)

# 注意这里的100其实给参数number_in
print(ret(100))

#注 意这里的200其实给参数number_in
print(ret(200))

Implementation process:

  1. test = RET (20 is) : perform the test function, DEF test_in  statement defines the skip function is not performed  , return test_in  returns a reference function;
  2. ret  At this point function test_in  , execution ret (100)  means that calls the function  test_in  , mass participation of 100.

 

3. Modify the external function variables

Modify global local variables can be modified by global keyword, how the closure modify variables outside a function of it?

  • Closure modify variables using nonlocal external function.

  • When the closure has external functions and variables of the same name, plus nonlocal closure will have access to the function of the external variables.

demo1

def counter(start=0):
    def incr():
        nonlocal start
        start += 1
        return start
    return incr

c1 = counter(5)
print(c1())  # 6
print(c1())  # 7

c2 = counter(50)
print(c2())  # 51
print(c2())  # 52

print(c1())  # 8
print(c1())  # 9

print(c2())  # 53
print(c2())  # 54

 

 

demo2

x = 300
def test1():
	x = 200
	def test2():
		nonlocal x  # 因为下面定义了局部的x,不写这句的话下面的输出语句会一位x是局部变量的x,报错
		print("----1----x=%d" % x)
		x = 100
		print("----2----x=%d" % x)
	return test2

t1 = test1()
t1()

Output:

----1----x=200
----2----x=100

Note: The above nonlocal method is not applicable and python2 .

 

 

-----end-----

Published 50 original articles · won praise 10 · views 6605

Guess you like

Origin blog.csdn.net/qq_23996069/article/details/104527503