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) >>> 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']
属性 __code__ を参照すると、コンパイルされた関数本体に対応するコードオブジェクトが得られます。
  • コードオブジェクト c のクラスが code だと分かります。
つまり、コードオブジェクト c は、クラス code のインスタンスです。
■ 属性:co_argcount
>>> c.co_argcount
3
属性 co_argcount を参照すると、位置引数の個数が得られます。
  • これには、規定値を持つ引数も含まれます。
ここでは、3つの引数 start,stop,step が存在します。
■ 属性: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_nlocals
>>> c.co_nlocals
5
属性 co_nlocals を参照すると、局所変数(引数も含めて)の個数が得られます。
■ 属性: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);
属性 co_varnames を参照すると、局所変数(引数も含めて)の名前を列挙したタプルが得られます。 》こちらに移動中です《TOP
# ---------------------------------------- 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

関連記事

Last updated♪2009/11/14