高度な閉鎖のpython [メモ]

高度な閉鎖のpython [メモ]

ディレクトリ

1.問題に

2.クロージャとは何ですか?(フォーカス)

3.変更外部関数変数


クロージャの導入に問題に取り組むことでまず、次に閉鎖プロセス分析を解釈して実行します。

1.問題に

例えば、Y = KX + B、複数の点への線を計算する、すなわちxの値yの値を算出します。

# 问题:初中里学过函数,例如 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)

第六に、ソリューションの閉鎖:

機能create_y変数kは、bがクロージャを構成しています。クロージャの作成では、我々はBショーこれら二つの変数の値は、パラメータk line_6を渡します。これは、最終形態(Y = KX + B)関数を決定します。私たちは、あなたが一次関数の異なる発現を得ることができ、パラメータK、Bを変更する必要があります。これを見ると、クロージャは、コードの再利用性を向上させるための役割を担っています。何クロージャがない場合、たび線形関数は、K、B、Xに記載の時間を作成する必要があります。複数のパラメータのためのコードの移植性を減らし、渡します。

(注:クロージャのためには、メモリを消費し、ローカル変数は、外部関数で放出されていない、ローカル変数、外部関数引用しました)

 

思考:関数、匿名関数、クロージャは、オブジェクトが引数が時に行う、違いは何ですか?

  1. 匿名関数は基本的な機能をシンプルに行うことができ、これは合格である関数への参照のみの機能(注:ラムダキーワードによって作成された匿名関数、コロンと表情一つだけを持っているが続きます)。
  2. より複雑な機能を完了するために通常の関数、送信された参照機能を機能のみ。
  3. 完全な、より複雑な機能にクロージャは、クロージャに送信される機能やデータ、従ってデータ転送機能である+(単純)。
  4. オブジェクトは、それが送信され、最も複雑な機能を完了するために大量のデータを多くの特徴+(プロパティとメソッドの数を使用することができる)ので、データ送信機能+です。

 

2.クロージャとは何ですか?(フォーカス)

内部関数次いで(機能多層ネストされた定義)関数を定義し、この関数は、外部変数の関数を使用し、この関数が使用され、そしていくつかの変数クロージャと呼ばれます。

# 定义一个函数
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))

実装プロセス:

  1. テスト= RET(20である):テスト機能を実行DEF test_inと  文はスキップ機能が定義され実行されない  、test_inとリターン  戻り参照機能と、
  2. RET  この点関数でtest_inと  、実行RET(100)  関数呼び出し手段  test_inとを  、100の質量参加。

 

3.変更外部関数変数

クロージャはその関数の外の変数を変更する方法、グローバルローカル変数はグローバルキーワードで変更することができます修正しますか?

  • クロージャーは、非ローカル外部関数を使用して変数を変更します。

  • クロージャは、外部関数と同じ名前の変数に加え、非ローカル閉鎖を持っている場合は、外部変数の関数にアクセスできるようになります。

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()

出力:

---- ---- 1、X = 200
---- 2 ---- X = 100

注:上記のローカル以外の方法が適用とpython2ではありません

 

 

- - -終わり - - -

公開された50元の記事 ウォン称賛10 ビュー6605

おすすめ

転載: blog.csdn.net/qq_23996069/article/details/104527503