オブジェクトの情報を探る(7) - コードオブジェクト

【 目次 】

コードオブジェクト

コードオブジェクトって何?

公式ドキュメントには

「Python/C API リファレンスマニュアル」には

CのAPIまで深入りしたくないのでここまでにして、

コンパイルされたバイトコードをオブジェクトとしてアクセスできるらしい。
そしてそのコードオブジェクトの属性よりソースコードのいろいろな情報が得られるという事。

コードオブジェクトの属性

コードオブジェクトの属性で何がアクセスできるかというと

公式ドキュメントの表より、
コードオブジェクトの部分を抜き出すと

属性 説明
co_argcount 引数の数 (* や ** 引数は含まない)
co_code コンパイルされたバイトコードそのままの文字列
co_consts バイトコード中で使用している定数のタプル
co_filename コードオブジェクトを生成したファイルのファイル名
co_firstlineno Python ソースコードの先頭行
co_flags 以下の値の組み合わせ: 1=optimized , 2=newlocals , 4=*arg , 8=**arg
co_lnotab 行番号からバイトコードインデックスへの変換表を文字列にエンコードしたもの
co_name コードオブジェクトが定義されたときの名前
co_names ローカル変数名のタプル
co_nlocals ローカル変数の数
co_stacksize 必要とされる仮想マシンのスタックスペース
co_varnames 引数名とローカル変数名のタプル

コードオブジェクトは、フレームオブジェクト関数オブジェクトの属性などから取得する事ができる。
以下のコードは関数のコードオブジェエクトの各属性を表示する例である。

def func(arg1, arg2):
    l_var = "l_var"
    return arg1 + arg2 + l_var

attr_dict = {
    "co_argcount":u"引数の数",
#    "co_code":u"コンパイルされたバイトコード文字列",
    "co_consts":u"バイトコード中で使用している定数のタプル",
    "co_filename":u"ファイルのファイル名",
    "co_firstlineno":u"ソースコードの先頭行",
    "co_flags":u"以下の値の組み合わせ: 1=optimized , 2=newlocals , 4=*arg , 8=**arg",
#    "co_lnotab":u"行番号からバイトコードインデックスへの変換表を文字列にエンコードしたもの",
    "co_name":u"関数名",
    "co_names":u"ローカル変数名のタプル",
    "co_nlocals":u"ローカル変数の数",
    "co_stacksize":u"必要とされる仮想マシンのスタックスペース",
    "co_varnames":u"引数名とローカル変数名のタプル"
 }

code_object = func.func_code
for attr_name, attr_discript in sorted(attr_dict.iteritems()):
    print attr_discript
    print attr_name, "=", getattr(code_object, attr_name)

実行結果

引数の数
co_argcount = 2
バイトコード中で使用している定数のタプル
co_consts = (None, 'l_var')
ファイルのファイル名
co_filename = C:\Rd\Python\pleiades-e4.4-python-jre_20140926\pleiades\workspace\Python2Test\src\tmp.py
ソースコードの先頭行
co_firstlineno = 3
以下の値の組み合わせ: 1=optimized , 2=newlocals , 4=*arg , 8=**arg
co_flags = 67
関数名
co_name = func
ローカル変数名のタプル
co_names = ()
ローカル変数の数
co_nlocals = 3
必要とされる仮想マシンのスタックスペース
co_stacksize = 2
引数名とローカル変数名のタプル
co_varnames = ('arg1', 'arg2', 'l_var')

ソースコードの取得

コードオブジェクトからソースコード文字列を取得するには inspectモジュールのgetsource関数を使って

import inspect

print "コードオブジェクトよりソースコードを取得"
source_text = inspect.getsource(code_object)
print source_text

実行結果

コードオブジェクトよりソースコードを取得
def func(arg1, arg2):
    l_var = "l_var"
    return arg1 + arg2 + l_var
ページのトップへ戻る