Python nonlocal
ステートメントは何をしますか(Python 3.0以降)?
Pythonの公式Webサイトにhelp("nonlocal")
はドキュメントがなく、動作しません。
"There is no documentation for nonlocal".
実際、help(keyword_in_string)
Python 3以降のドキュメントで実行できます
Python nonlocal
ステートメントは何をしますか(Python 3.0以降)?
Pythonの公式Webサイトにhelp("nonlocal")
はドキュメントがなく、動作しません。
"There is no documentation for nonlocal".
実際、help(keyword_in_string)
Python 3以降のドキュメントで実行できます
回答:
使用せずにこれを比較してくださいnonlocal
:
x = 0
def outer():
x = 1
def inner():
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 1
# global: 0
このために、使用してnonlocal
、どこinner()
のことはx
今もあるouter()
S ' x
:
x = 0
def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 2
# global: 0
を使用
global
するx
と、適切に「グローバル」な値にバインドされます。x = 0 def outer(): x = 1 def inner(): global x x = 2 print("inner:", x) inner() print("outer:", x) outer() print("global:", x) # inner: 2 # outer: 1 # global: 2
「python nonlocal」をグーグルで検索すると、提案、PEP 3104が見つかりました。これは、ステートメントの背後にある構文と理由を完全に説明しています。つまり、global
関数に対してグローバルでもローカルでもない変数を参照するために使用されることを除いて、ステートメントとまったく同じように機能します。
これでできることの簡単な例を次に示します。カウンタージェネレーターは、これを使用するように書き換えることができるため、クロージャーを使用する言語のイディオムに似ています。
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
明らかに、あなたはこれをジェネレータとして書くことができます:
def counter_generator():
count = 0
while True:
count += 1
yield count
しかし、これは完全に慣用的なpythonですが、最初のバージョンは初心者にはもう少しわかりやすいようです。返された関数を呼び出してジェネレータを適切に使用することは、混乱の共通点です。最初のバージョンは明示的に関数を返します。
nonlocal
、Pythonでステートメントを説明することを目的としています。自然数のシーケンスが必要な場合、Pythonイディオムは実際にはitertools.count()
@ooboo:
ソースコードの参照ポイントに「最も近い」ものを1つ使用します。これは「字句スコープ」と呼ばれ、40年以上の間標準となっています。
Pythonのクラスメンバーは、実際には、 __dict__
にあり、字句スコープによって到達されることはありません。
指定しない場合nonlocal
しかしやるx = 7
、それが「X」の新しいローカル変数を作成します。を指定nonlocal
すると、「最も近い」「x」が検出され、それに割り当てられます。指定した場合nonlocal
して「x」がない場合は、エラーメッセージが表示されます。
global
一番外側のキーワードを除いて、他のすべての "x"を喜んで無視するので、このキーワードはいつも奇妙に思えました。変だ。
help( 'nonlocal')
nonlocal
ステートメント
nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
の
nonlocal
ステートメントにより、リストされた識別子は、最も近い囲みスコープで以前にバインドされた変数を参照します。バインディングのデフォルトの動作は、最初にローカル名前空間を検索することなので、これは重要です。このステートメントを使用すると、カプセル化されたコードで、グローバル(モジュール)スコープ以外のローカルスコープの外部にある変数を再バインドできます。
nonlocal
ステートメントにリストされている名前とは異なり、ステートメントに リストされている名前global
、囲んでいるスコープ内の既存のバインディングを参照する必要があります(新しいバインディングを作成するスコープを明確に決定することはできません)。
nonlocal
ステートメントにリストされている名前は、ローカルスコープの既存のバインディングと衝突してはなりません。以下も参照してください。
PEP 3104-外部スコープ内の名前へのアクセスステートメント
の仕様nonlocal
。関連するヘルプトピック:グローバル、NAMESPACES
ソース:Python言語リファレンス
help()
キーワードで使用できるとは思いもしませんでした(そして今、私の心は吹き飛ばされhelp()
ています:引数なしでインタラクティブになります)。
Python 3リファレンスからの引用:
非ローカルステートメントにより、リストされた識別子は、グローバルを除いて、最も近い囲みスコープで以前にバインドされた変数を参照します。
参考文献で述べたように、いくつかのネストされた関数の場合、最も近い囲み関数の変数のみが変更されます。
def outer():
def inner():
def innermost():
nonlocal x
x = 3
x = 2
innermost()
if x == 3: print('Inner x has been modified')
x = 1
inner()
if x == 3: print('Outer x has been modified')
x = 0
outer()
if x == 3: print('Global x has been modified')
# Inner x has been modified
「最も近い」変数は、数レベル離れている場合があります。
def outer():
def inner():
def innermost():
nonlocal x
x = 3
innermost()
x = 1
inner()
if x == 3: print('Outer x has been modified')
x = 0
outer()
if x == 3: print('Global x has been modified')
# Outer x has been modified
ただし、グローバル変数にすることはできません。
def outer():
def inner():
def innermost():
nonlocal x
x = 3
innermost()
inner()
x = 0
outer()
if x == 3: print('Global x has been modified')
# SyntaxError: no binding for nonlocal 'x' found
a = 0 #1. global variable with respect to every function in program
def f():
a = 0 #2. nonlocal with respect to function g
def g():
nonlocal a
a=a+1
print("The value of 'a' using nonlocal is ", a)
def h():
global a #3. using global variable
a=a+5
print("The value of a using global is ", a)
def i():
a = 0 #4. variable separated from all others
print("The value of 'a' inside a function is ", a)
g()
h()
i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)
「非ローカル」内部関数(つまり、ネストされた内部関数)を使用すると、外部親関数の特定の変数に対する読み取りおよび「書き込み」権限を取得できます。そして非ローカルは内部関数内でのみ使用できます。例:
a = 10
def Outer(msg):
a = 20
b = 30
def Inner():
c = 50
d = 60
print("MU LCL =",locals())
nonlocal a
a = 100
ans = a+c
print("Hello from Inner",ans)
print("value of a Inner : ",a)
Inner()
print("value of a Outer : ",a)
res = Outer("Hello World")
print(res)
print("value of a Global : ",a)