__builtins__と__builtin__
globals関数やdir関数を使ってモジュールのグローバルシンボルを調べてみると__builtins__という変数(シンボル)が定義されているのがわかる。
この__builtins__という変数は何の為に定義されているのだろう。
27.3. __builtin__ — 組み込みオブジェクト — Python 2.7ja1 documentationによると
ほとんどのモジュールではグローバル変数の一部として __builtins__ ('s' に注意) が利用できるようになっています。
__builtins__ の内容は通常 __builtin__ モジュールそのものか、あるいは __builtin__ モジュールの __dict__ 属性です。
とある。
pythonには標準で使われる組み込み関数が定義されていて、いつでも使う事ができる。
この組み込み関数は__builtin__というモジュールに定義されていて、起動時に自動的にimportされ、組み込み関数にアクセスするための情報は__builtins__という変数に格納されている。
これにより、組み込み関数はモジュール名を付けなくても関数名だけで呼び出す事ができる仕組みになっているようだ。
例えば、オブジェクトの長さを返すlen関数の場合で言えば、
以下のプログラム例のように関数名だけを使ってlen(a)
としても、明示的に、__builtins__変数を利用して__builtins__.len(a)
としてもどちらを使って呼び出しても良い事になる。
lenでも__builtins__.lenでも呼び出せる
a=['x','y','z'] print len(a) print __builtins__.len(a)
また、通常のモジュールのimportと同じように、明示的__builtin__モジュールをimportして、
明示的__builtin__をimport
import __builtin__ a=['x','y','z'] print __builtin__.len(a)
とする事もできる。
globals関数やdir関数を使ってモジュールのグローバルシンボルを調べてみると__builtins__というシンボルは、メインモジュールでは__builtin__ モジュールそのものを指すが、サブモジュールでは__builtin__ モジュールの __dict__ 属性を指すようだ。
その事は以下のプログラムにより確認できる。
main.py
#coding: UTF-8 print u"メインモジュールの__builtins__" print type(globals()["__builtins__"]) print globals()["__builtins__"] import sub
sub.py
#coding: UTF-8 print u"サブモジュールの__builtins__" print type(globals()["__builtins__"]) for key, value in globals()["__builtins__"].items(): print "\t",key
実行結果
メインモジュールの__builtins__ <type 'module'> <module '__builtin__' (built-in)> サブモジュールの__builtins__ <type 'dict'> bytearray IndexError all help vars SyntaxError unicode UnicodeDecodeError memoryview isinstance copyright NameError BytesWarning dict input oct bin SystemExit StandardError format repr sorted False RuntimeWarning list iter reload Warning __package__ round dir cmp set bytes reduce intern issubclass Ellipsis EOFError locals BufferError slice FloatingPointError sum getattr abs exit print True FutureWarning ImportWarning None hash ReferenceError len credits frozenset __name__ ord super TypeError license KeyboardInterrupt UserWarning filter range staticmethod SystemError BaseException pow RuntimeError float MemoryError StopIteration globals divmod enumerate apply LookupError open quit basestring UnicodeError zip hex long next ImportError chr xrange type __doc__ Exception tuple UnicodeTranslateError reversed UnicodeEncodeError IOError hasattr delattr setattr raw_input SyntaxWarning compile ArithmeticError str property GeneratorExit int __import__ KeyError coerce PendingDeprecationWarning file EnvironmentError unichr id OSError DeprecationWarning min UnicodeWarning execfile any complex bool ValueError NotImplemented map buffer max object TabError callable ZeroDivisionError eval __debug__ IndentationError AssertionError classmethod UnboundLocalError NotImplementedError AttributeError OverflowError WindowsError
メインモジュールの__builtins__変数の型はmodule型であり、その内容は__builtin__モジュール。
サブモジュールの__builtins__変数の型はdictであり、その内容は__builtin__モジュールのシンボルを指している事がわかる。
__builtins_\変数と__builtin__モジュールの使い道
では、__builtins__にどのような使い道があるのかというと、組込み関数と同名のユーザ定義関数を定義した場合に、元の組込み関数は隠蔽されてしまうが、__builtins__や__builtin__を使う事で以下のように元の関数を呼び出す事ができる。
HelloAndroid.java
#coding: UTF-8 a=['x','y','z'] # 組込み関数lenを実行 print len(a) # ユーザ定義関数lenを定義 def len(arg): return __builtins__.len(arg)-1 # ユーザ定義関数lenが実行される。 print len(a) # __builtins__を指定して明示的に組込み関数lenを実行。 print __builtins__.len(a) # __builtin__を指定して明示的に組込み関数lenを実行。 import __builtin__ print __builtin__.len(a) # ユーザ定義関数lenのシンボルを削除 del(len) # 元の組込み関数lenが実行される。 print len(a)