-1

このコードがあります:

def f():
  x = m 
  m = 2 

def g():
  x = m

f() # UnboundLocalError: local variable 'm' referenced before assignment
g() # NameError: global name 'm' is not defined

どちらの関数本体にもm、使用時に定義されていない変数が使用されていますが、エラー メッセージは異なります。Python は、関数で定義されている変数を使用する前に ( function のように) 知っていますfか? エラーメッセージが異なるのはなぜですか?

4

6 に答える 6

2

関数内のどこかに変数への割り当てがある場合、その関数内のどこでもローカル変数と見なされます。これは、関数 の場合、へのアクセスの試行後にf()への割り当てが行われたとしても、行はローカル スコープ内でのみ名前を検索することを意味します。これが、エラー メッセージがローカル変数として参照される理由です。mmx = mmf()m

関数g()には への代入がないmため、行は次の順序x = mで検索されますm

  • 最初に検索される最も内側のスコープには、ローカル名が含まれます
  • 最も近い外側のスコープから検索される外側の関数のスコープには、非ローカル名と非グローバル名が含まれます
  • 最後から2番目のスコープには、現在のモジュールのグローバル名が含まれています
  • 最も外側のスコープ (最後に検索される) は、組み込みの名前を含む名前空間です

"global name 'm' is not defined"のエラー メッセージg()は、最後に検索された場所であるため、グローバル スコープを参照しています (組み込みを除くが、"the name ' のようなメッセージがあると混乱するでしょう) m' が組み込み名前空間に見つかりませんでした」)。

globalornonlocalステートメントを使用してこの動作を変更できることに注意してください( nonlocalPython 3.x にのみ存在します)。

于 2013-05-28T16:29:56.277 に答える
1

Python は、呼び出すとすぐにそれをチェックします。

インポートしてインタープリターに直接入力する場合、構文規則に違反しているかどうかだけが問題になります。このレベルでは、ローカルまたはグローバルは気にしません。

>>> def foo():
...     print locals()
...     bar = 34
...     print locals()
...     DIP = SET
...
>>>
>>> foo()
{}
{'bar': 34}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in foo
NameError: global name 'SET' is not defined

それは上から下に実行され、 locals() と globals() をチェックし、その変数を見つけたら大丈夫で、それを使って何でもします。

定義とサブ定義でも機能します..または割り当てている他のものでも機能します

>>> def foo():
...     bar()
...     def bar():
...         print("never gonna give you up")
...
>>>
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'bar' referenced before assignment
于 2013-05-28T16:40:22.123 に答える
0
def f():
  x = m 
  m = 2 

上記の関数が解析されたとき、python はそれmがローカル変数であると認識m = 2し、関数が実際に呼び出されると、ローカル スコープでまだ定義されていないx = mため、エラーが発生します。m

def g():
  x = m

この pythonmでは、グローバル スコープからの何らかの値になると考えており、最初にグローバル名前空間を検索し、次に組み込みを検索しますが、mどこにも見つからない場合はエラーが発生します。

>>> m = 1
>>> def g():
       x = m
>>> g()         #works fine because `m` is found in global scope

>>> def g():
       x = sum
>>> g()         # sum is found in built-ins

グローバル変数を変更するには、次を使用しますglobal

>>> m = 1
>>> def g():
       global m
       m += 1
...     
>>> g()
>>> m
2
于 2013-05-28T16:32:17.910 に答える
0

はい。関数内の任意の場所で (globalキーワードを使用せずに) 変数に割り当てると、Python は関数内のその名前へのすべての参照をローカルとして扱います。

于 2013-05-28T16:27:47.360 に答える
0

global m関数内で使用する必要があります

于 2013-05-28T16:43:23.033 に答える
0

関数を実行すると、実際__call()__には関数オブジェクトが呼び出されます。

関数オブジェクトは、スクリプトが解析されるときにスクリプト グローバル名前空間に作成されます。作成されましたが、実行されませんでした。

解析プロセスの一部として、オブジェクトの名前空間が計算されます。したがって、インタプリタは、どの変数がいつ存在するかを実際に知ることができます。

于 2013-05-28T16:31:05.250 に答える