Python.use(better) #def: 関数 -- コードオブジェクト
‖記事一覧‖ Python.use(better)《Python3.1》
def: 関数 -- コードオブジェクト
《著》森こねこ、小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28
「関数」に関する基本的な理解を深めます。
※ Python1.5 で作成した例題を、Python3.1 で再構成しました。
関数:コードオブジェクト
コードオブジェクト〔code object〕は、コンパイルされた関数の本体を表現したものです。バイトコードも「オブジェクト」として、他のオブジェクトと同等に扱えます。すると、
- 任意の「インスタンスオブジェクト」が「属性」を介して他のオブジェクトを参照できるように、
- 任意の「コードオブジェクト」も「属性」を介して他のオブジェクトを参照できます。
事例:myrange
以下は(他項 で作成した)次の関数 myrange を事例に解説します。
def myrange(start=0, stop=None, step=1): s = [] while start < stop: s.append(start) start += step return s
属性:__code__
>>> c <code object myrange at 0x12568d8, file ".../function.py", line ...> >>> type(c)属性 __code__ を参照すると、コンパイルされた関数本体に対応するコードオブジェクトが得られます。>>> dir(c) ['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
- コードオブジェクト c のクラスが code だと分かります。
■ 属性:co_argcount
>>> c.co_argcount 3属性 co_argcount を参照すると、位置引数の個数が得られます。
- これには、規定値を持つ引数も含まれます。
■ 属性:co_filename
>>> c.co_filename '/Users/sketch/home_Python/alpha/function.py'属性 co_filename を参照すると、コンパイルされたコードを含むファイルの名前が得られます。
■ 属性:co_firstlineno
>>> c.co_firstlineno 162属性 co_firstlineno を参照すると、関数定義が始まる行番号が得られます。
■ 属性:co_name
>>> c.co_name 'myrange'属性 co_name を参照すると、関数の名前(文字列)が得られます。
事例:myrange
以下は(他項 で作成した)次の関数 myrange を事例に解説します。def scale(n, offset=1): s = [] for e in range(offset,n+offset): c = "." if not e%10: c = str(e//10) elif not e%5: c = "+" s.append(c) return "".join(s)
■ 属性:co_consts
>>> c.co_consts (None, '.', 10, 5, '+', '')属性 co_consts を参照すると、リテラル要素を列挙したタプルが得られます。
■ 属性:co_names
>>> c.co_names ('range', 'str', 'append', 'join')属性 co_names を参照すると、関数の名前(文字列)が得られます。
■ 属性:co_varnames
>>> c.co_varnames ('n', 'offset', 's', 'e', 'c')
- co_varnames is a tuple containing the names of the local variables (starting with the argument names);
# ---------------------------------------- c.co_* >>> c.co_argcount 2 >>> c.co_cellvars () >>> c.co_code b'g\x00\x00}\x02\x00x^\x00t\x00\x00|\x01\x00|\x00\x00|\x01\x00\x17\x83\x02\x00D]I\x00}\x03\x00d\x01\x00}\x04\x00|\x03\x00d\x02\x00\x16sC\x00t\x01\x00|\x03\x00d\x02\x00\x1a\x83\x01\x00}\x04\x00n\x13\x00|\x03\x00d\x03\x00\x16sV\x00d\x04\x00}\x04\x00n\x00\x00|\x02\x00j\x02\x00|\x04\x00\x83\x01\x00\x01q\x1a\x00Wd\x05\x00j\x03\x00|\x02\x00\x83\x01\x00S' >>> c.co_filename '/Users/sketch/home_Python/alpha/ape/ex_function/function.py' >>> c.co_firstlineno 151 >>> c.co_flags 83 >>> c.co_freevars () >>> c.co_kwonlyargcount 0 >>> c.co_lnotab b'\x00\x01\x06\x01\x14\x00\x06\x01\x06\x01\n\x01\x13\x01\n\x01\t\x01\x11\x01' >>> c.co_name 'scale' >>> c.co_stacksize 4