web-dev-qa-db-ja.com

Pythonでの "global"キーワードの使用

ドキュメントを読んで理解したことは、Pythonには関数用に別の名前空間があり、その関数でグローバル変数を使用したい場合はglobalを使用する必要があります。

私はPython 2.7を使っていて、この小さなテストを試しました

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

globalがなくても問題なく動作しているようです。グローバル変数に問題なくアクセスできました。

私は何かが足りないのですか?また、以下はPythonのドキュメントからの抜粋です。

グローバルステートメントにリストされている名前は、仮パラメーターとして、またはforループ制御ターゲット、クラス定義、関数定義、またはインポートステートメントとして定義してはなりません。

形式パラメータとクラス定義は私には意味がありますが、forループ制御ターゲットと関数定義の制限を理解することはできません。

265
nik

キーワードglobalは、グローバル変数をローカルコンテキストで変更または作成する場合にのみ役立ちますが、グローバル変数を作成することがめったに良い解決策と見なされることはありません。

def bob():
    me = "locally defined"    # Defined only in local context
    print me

bob()
print me     # Asking for a global variable

上記はあなたに与えるでしょう:

locally defined
Traceback (most recent call last):
  File "file.py", line 9, in <module>
    print me
NameError: name 'me' is not defined

global文を使用すると、変数は関数の範囲外で使用可能になり、実質的にグローバル変数になります。

def bob():
    global me
    me = "locally defined"   # Defined locally but declared as global
    print me

bob()
print me     # Asking for a global variable

だから上記のコードはあなたを与えるでしょう:

locally defined
locally defined

さらに、pythonの性質上、ローカルコンテキストで関数、クラス、その他のオブジェクトを宣言するためにglobalを使用することもできます。何かがうまくいかなかったりデバッグが必要な場合は悪夢を引き起こすので私はそれに対して忠告しますが。

344
unode

globalキーワードなしでグローバル変数にアクセスできますが、それらを変更したい場合はglobalキーワードを使用する必要があります。例えば:

foo = 1
def test():
    foo = 2 # new local foo

def blub():
    global foo
    foo = 3 # changes the value of the global foo

あなたの場合は、リストsubにアクセスしているだけです。

199
Ivo Wetzel

これは、名前へのアクセスとスコープ内での binding の違いです。

値を読み取るために変数を調べているだけであれば、ローカルスコープだけでなくグローバルスコープにもアクセスできます。

ただし、ローカルスコープにない名前の変数に代入すると、その名前はこのスコープに binding となります(その名前がグローバルとしても存在する場合は非表示になります)。

グローバル名に割り当てることができるようにしたい場合は、新しいローカル名をバインドするのではなく、グローバル名を使用するようにパーサーに指示する必要があります。これが 'global'キーワードの機能です。

ブロック内の任意の場所にバインドすると、そのブロック内のどこにでも名前がバインドされます。

>>> a = 1
>>> def p():
    print(a) # accessing global scope, no binding going on
>>> def q():
    a = 3 # binding a name in local scope - hiding global
    print(a)
>>> def r():
    print(a) # fail - a is bound to local scope, but not assigned yet
    a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    r()
  File "<pyshell#32>", line 2, in r
    print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>> 
66
pycruft

他の答えはあなたの質問に答えます。 Pythonの名前について知っておくべきもう1つの重要なことは、名前がスコープごとにローカルかグローバルかということです。

例えばこれを考えてみましょう。

value = 42

def doit():
    print value
    value = 0

doit()
print value

value = 0ステートメントはローカル変数に代入され、doit()関数の外側で宣言された同じ変数の値には影響を与えないとおそらく想像できるでしょう。 上記のコードが実行されないことを発見するともっと驚かれるかもしれません。 関数内のステートメントprint valueUnboundLocalError.を生成します

その理由は、Pythonは関数内の他の場所でvalueという名前を割り当て、そしてvalueはどこでもglobalとして宣言されていないことに気づいたからです。それはそれをローカル変数にします。しかし、印刷しようとすると、ローカル名はまだ定義されていません。この場合のPythonの はフォールバックしません 他の言語のように、グローバル変数としての名前の検索に戻ります。基本的に、関数内で同じ名前のローカル変数 where - を定義した場合、グローバル変数にアクセスすることはできません。

47
kindall

名前へのアクセスと名前の割り当ては異なります。あなたの場合は、名前にアクセスしているだけです。

関数内で変数に代入した場合、その変数はグローバル宣言しない限りローカルであると見なされます。それがなければ、それは地球規模であると考えられます。

>>> x = 1         # global 
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():   
        x = 2        # local x
        print x 

>>> x            # global x
1
>>> foo()        # prints local x
2
12
user225312
  • キーワードglobalがなくてもグローバルキーワードにアクセスできます
  • それらを変更できるようにするには、キーワードがグローバルであることを明示的に述べる必要があります。それ以外の場合、キーワードはローカルスコープで宣言されます。

例:

words = [...] 

def contains (Word): 
    global words             # <- not really needed
    return (Word in words) 

def add (Word): 
    global words             # must specify that we're working with a global keyword
    if Word not in words: 
        words += [Word]
6
martynas

関数の外側で宣言された変数はすべてグローバルであると見なされます。変数をグローバルであると指定する必要があるのは、関数の内側(コンストラクタを除く)からそれらを宣言するときだけです。

2
Jesus Ramos

私はあなたに簡単な例を挙げるでしょう:このコードについて考えてください:

myVar = 0 
print (myVar )      # 01 line: returns 0

def func():
    myVar  = "def"
    print (myVar )

func()              # 02 line: returns def
print (myVar )      # 03 line: returns 0

ご覧のとおり、コードの最後の行は0を返します。関数内で myVar 変数は再割り当てされずに変更され、変更されます メインmyVar変数に影響を与えずに呼び出された場合のみこれは、our関数内で定義されているため(ローカル変数であることを意味します) しかし、globalキーワードを使用して以下のようになります。

 myVar  = 0 
print (myVar )       # 01 Line : returns 0

def func():
    global myVar 
    myVar  = "def"
    print (myVar )

func()               # 02 Line : returns def
print (myVar )       # 03 Line : returns def

私たちは実際にpythonにdefの中のこの変数がローカルではないことを命じ、それを変更するために myVar と名付けられたグローバル変数を使います。

0
a_m_dev

Globalは、変数を「Global」にします。

def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

これにより、 'x'は関数外の通常の変数のように機能します。あなたがグローバルを取り出した場合、それは関数の中に変数を表示することができないのでそれはエラーになります。

def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)
0
Michael

つまり、次のことはしないでください。

x = 1

def myfunc():
  global x

  # formal parameter
  def localfunction(x):
    return x+1

  # import statement
  import os.path as x

  # for loop control target
  for x in range(10):
    print x

  # class definition
  class x(object):
    def __init__(self):
      pass

  #function definition
  def x():
    print "I'm bad"
0
ikostia

これはPython FAQで詳しく説明されています

Pythonのローカル変数とグローバル変数のルールは何ですか?

Pythonでは、関数内でのみ参照される変数は暗黙的にグローバルです。関数の本体内の任意の場所で変数に値が割り当てられている場合、明示的にグローバルとして宣言されていない限り、変数はローカルであると見なされます。

最初は少し驚くべきことでしたが、少し考えてみるとこれがわかります。一方では、割り当てられた変数にglobalを要求することで、意図しない副作用を防ぐことができます。一方、すべてのグローバル参照にglobalが必要な場合は、常にglobalを使用することになります。組み込み関数またはインポートされたモジュールのコンポーネントへのすべての参照をglobalとして宣言する必要があります。この混乱は、副作用を識別するためのglobal宣言の有用性を無効にします。

https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

0
user7610