__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)

参考記事

ページのトップへ戻る