メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年2月9日土曜日

[Python][お勉強] Python入門(25) - スコープ

今日もPython。

今日はスコープに関して学ぶ。


前提
Pythonでは変数は全て「名前空間」に属する。


モジュールのトップレベル変数
グローバル変数という。モジュール内(同一ファイル)であればグローバル変数として扱えるが、
モジュールの外からだとモジュールの属性として扱える。

グローバル変数
他言語のグローバル変数とは意味が違う。1ファイル全体が有効範囲。


ローカル変数
関数内での変数はその関数が呼び出された時点で作成される。その関数内においてのみ扱える変数。

関数内で代入された時点でローカル変数が作成される。
グローバル変数と同じ名前であっても関数内で代入されたらその時点でローカル変数が作成される。
よって無条件でグローバル変数を更新できない。
グローバル変数を更新したい場合はglobalステートメントを使用する。

Pythonでの3種類の名前空間
Pythonでは基本的に3種類の名前空間が存在する。
1つは「ローカルスコープ」、2つめは「グローバルスコープ」、3つめは「ビルトインスコープ」。
「ローカルスコープ」は「ローカル変数」の名前空間。「グローバルスコープ」は「グローバル変数」の名前空間。「ビルトインスコープ」はPython内で保持している__builtin__モジュールが属する名前空間。


LEGBルール
変数が使用されている場合、まずローカル変数であるかどうかを調べ、次に外側のローカル変数であるかどうか調べ、次にグローバル変数であるかどうか調べ、最後にビルトイン変数であるかどうか調べる。
このルールのこと。
「L」はLocal。「E」はEnclosing function's scopeの「E」。「G」はGlobalの「G」。「B」はBuiltinの「B]。


ビルトインスコープ
最初からimportもせずに使えるものでPythonプログラム全てのスコープ。
何が存在するのかは以下のようにすれば確認できる。


>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError',
'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
'Exception', 'False', 'FloatingPointError', 'FutureWarning',
'IOError', 'ImportError', 'IndentationError', 'IndexError',
'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError',
'NameError', 'None', 'NotImplemented', 'NotImplementedError',
'OSError', 'OverflowError', 'OverflowWarning', 'PendingDeprecationWarning',
'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError',
'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError',
'UnicodeTranslateError', 'UserWarning', 'ValueError', 'Warning',
'ZeroDivisionError', '__debug__', '__doc__', '__import__',
'__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer',
'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile',
'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir',
'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter',
'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help',
'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max',
'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit',
'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round',
'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum',
'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
>>>




globalステートメント
通常関数の中からグローバル変数の値を更新することはできない。がglobalステートメントを使用して宣言することでグローバル変数を更新することができる。


>>> X = 88
>>>
>>> def func():
... X = 99
...
>>> func()
>>> print X
88
>>>


このように通常は、func()内のXはローカル変数として扱われ、グローバル変数であるXとは別ものとして
扱われる。
globalステートメントを使うと、

>>> X = 88
>>>
>>> def func ():
... global X
... X = 99
...
>>> func()
>>> print X
99
>>>


のようにfunc()内の変数もグローバル変数として扱うことができる。
上記はfunc()内でグローバル変数を更新した例。


まとめ
代入した時点でスコープが決まる。スコープを例外的に扱いたい場合にはglobalステートメントを使用する。





おしまい。
.

0 コメント: