関数の __code__ 属性はコードオブジェクトを保持しており、関数の内部構造に関する詳細情報を提供します。
コードオブジェクトの主要属性
def example(a, b, *args, c=10, **kwargs): x = a + b y = c * 2 return x + y code = example.__code__
| co_name | 関数名 |
| co_filename | 定義されたファイル名 |
| co_firstlineno | 定義開始行番号 |
| co_argcount | 位置引数の数(*args を除く) |
| co_kwonlyargcount | キーワード専用引数の数 |
| co_varnames | ローカル変数名のタプル |
| co_freevars | 自由変数(クロージャで参照) |
| co_cellvars | セル変数(内部関数に渡す) |
| co_consts | 定数のタプル |
| co_code | バイトコード |
具体的な値を確認
print(code.co_name) # example print(code.co_argcount) # 2 (a, b) print(code.co_kwonlyargcount) # 1 (c) print(code.co_varnames) # ('a', 'b', 'c', 'args', 'kwargs', 'x', 'y') print(code.co_consts) # (None, 10, 2)
クロージャと自由変数
def outer(x): def inner(y): return x + y return inner closure = outer(10) print(closure.__code__.co_freevars) # ('x',)
co_freevars には、外側のスコープから参照している変数が記録されます。
コードオブジェクトの置き換え
コードオブジェクトを操作して関数の挙動を変えることも可能です(非推奨ですが理解として)。
def original(): return 1 def replacement(): return 2 original.__code__ = replacement.__code__ print(original()) # 2
実用的な活用
def get_function_info(func): code = func.__code__ return { "name": code.co_name, "args": code.co_varnames[:code.co_argcount], "file": code.co_filename, "line": code.co_firstlineno, }
コードオブジェクトの理解は、デバッガーやプロファイラの開発、動的コード生成に役立ちます。