Python/読解対象とするPythonコードと解析方法
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[Pythonを読む]]
#contents
*はじめに [#k27a077f]
オブジェクトに属性がどう保存されるのかを見ていきます。
ちなみにPythonの場合、メソッドも属性です。つまり、関数オ...
ともかく、対象とするプログラムはこちら。
#code(Python){{
class Foo:
def __init__(self, x):
self.x = x
def method(self):
print(self.x)
foo = Foo(123)
foo.method()
}}
*解析のための道具 [#u4647d7d]
「はじめに」で挙げたプログラムがどのようなバイトコードに...
まず先ほどのプログラムを文字列として定義します。
>>> src = '''
class Foo:
def __init__(self, x):
self.x = x
def method(self):
print(self.x)
foo = Foo(123)
foo.method()
'''
それを[[compile関数>https://docs.python.org/ja/3/library/...
>>> co = compile(src, '<string>', 'exec')
これでコードオブジェクトが出来上がります。
バイトコードを得るには[[disモジュール>https://docs.python...
>>> dis.dis(co)
2 0 LOAD_BUILD_CLASS
2 LOAD_CONST 0 (<code object...
4 LOAD_CONST 1 ('Foo')
6 MAKE_FUNCTION 0
8 LOAD_CONST 1 ('Foo')
10 CALL_FUNCTION 2
12 STORE_NAME 0 (Foo)
9 14 LOAD_NAME 0 (Foo)
16 LOAD_CONST 2 (123)
18 CALL_FUNCTION 1
20 STORE_NAME 1 (foo)
10 22 LOAD_NAME 1 (foo)
24 LOAD_ATTR 2 (method)
26 CALL_FUNCTION 0
28 POP_TOP
30 LOAD_CONST 3 (None)
32 RETURN_VALUE
2~10のあたり、もうすでに興味深いところですが一旦置いとい...
まず、「クラス定義」を表すコードオブジェクトは定数として...
>>> co.co_consts
(<code object Foo at 0x031936A8, file "<string>", line 2...
co_namesにコードで使われている「名前」が格納されています。
>>> co.co_names
('Foo', 'foo', 'method')
**クラス定義に踏み込む [#u256b392]
クラス定義はモジュール全体を表すコードオブジェクトの定数...
>>> dis.dis(co.co_consts[0])
2 0 LOAD_NAME 0 (__name__)
2 STORE_NAME 1 (__module__)
4 LOAD_CONST 0 ('Foo')
6 STORE_NAME 2 (__qualname__)
3 8 LOAD_CONST 1 (<code object...
10 LOAD_CONST 2 ('Foo.__init_...
12 MAKE_FUNCTION 0
14 STORE_NAME 3 (__init__)
6 16 LOAD_CONST 3 (<code object...
18 LOAD_CONST 4 ('Foo.method')
20 MAKE_FUNCTION 0
22 STORE_NAME 4 (method)
24 LOAD_CONST 5 (None)
26 RETURN_VALUE
__init__メソッドの定義、methodメソッドの定義はさらに「ク...
>>> dis.dis(co.co_consts[0].co_consts[1])
4 0 LOAD_FAST 1 (x)
2 LOAD_FAST 0 (self)
4 STORE_ATTR 0 (x)
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> dis.dis(co.co_consts[0].co_consts[3])
7 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (self)
4 LOAD_ATTR 1 (x)
6 CALL_FUNCTION 1
8 POP_TOP
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
ところでそれぞれのco_namesを見てみましょう。
>>> co.co_consts[0].co_consts[1].co_names
('x',)
>>> co.co_consts[0].co_consts[3].co_names
('print', 'x')
selfはいません。引数(と今回はないけどローカル変数)はco_...
>>> co.co_consts[0].co_consts[1].co_varnames
('self', 'x')
>>> co.co_consts[0].co_consts[3].co_varnames
('self',)
なお、1番目(__init__メソッドに対応するコードオブジェクト...
しれっとローカル変数と書きましたがトップレベルの変数(foo...
*おわりに [#mec2a46e]
今回はとりあえず手始めにクラス定義がどのようなバイトコー...
ところで、もちろんdisモジュールで出てくるのはPython処理系...
終了行:
[[Pythonを読む]]
#contents
*はじめに [#k27a077f]
オブジェクトに属性がどう保存されるのかを見ていきます。
ちなみにPythonの場合、メソッドも属性です。つまり、関数オ...
ともかく、対象とするプログラムはこちら。
#code(Python){{
class Foo:
def __init__(self, x):
self.x = x
def method(self):
print(self.x)
foo = Foo(123)
foo.method()
}}
*解析のための道具 [#u4647d7d]
「はじめに」で挙げたプログラムがどのようなバイトコードに...
まず先ほどのプログラムを文字列として定義します。
>>> src = '''
class Foo:
def __init__(self, x):
self.x = x
def method(self):
print(self.x)
foo = Foo(123)
foo.method()
'''
それを[[compile関数>https://docs.python.org/ja/3/library/...
>>> co = compile(src, '<string>', 'exec')
これでコードオブジェクトが出来上がります。
バイトコードを得るには[[disモジュール>https://docs.python...
>>> dis.dis(co)
2 0 LOAD_BUILD_CLASS
2 LOAD_CONST 0 (<code object...
4 LOAD_CONST 1 ('Foo')
6 MAKE_FUNCTION 0
8 LOAD_CONST 1 ('Foo')
10 CALL_FUNCTION 2
12 STORE_NAME 0 (Foo)
9 14 LOAD_NAME 0 (Foo)
16 LOAD_CONST 2 (123)
18 CALL_FUNCTION 1
20 STORE_NAME 1 (foo)
10 22 LOAD_NAME 1 (foo)
24 LOAD_ATTR 2 (method)
26 CALL_FUNCTION 0
28 POP_TOP
30 LOAD_CONST 3 (None)
32 RETURN_VALUE
2~10のあたり、もうすでに興味深いところですが一旦置いとい...
まず、「クラス定義」を表すコードオブジェクトは定数として...
>>> co.co_consts
(<code object Foo at 0x031936A8, file "<string>", line 2...
co_namesにコードで使われている「名前」が格納されています。
>>> co.co_names
('Foo', 'foo', 'method')
**クラス定義に踏み込む [#u256b392]
クラス定義はモジュール全体を表すコードオブジェクトの定数...
>>> dis.dis(co.co_consts[0])
2 0 LOAD_NAME 0 (__name__)
2 STORE_NAME 1 (__module__)
4 LOAD_CONST 0 ('Foo')
6 STORE_NAME 2 (__qualname__)
3 8 LOAD_CONST 1 (<code object...
10 LOAD_CONST 2 ('Foo.__init_...
12 MAKE_FUNCTION 0
14 STORE_NAME 3 (__init__)
6 16 LOAD_CONST 3 (<code object...
18 LOAD_CONST 4 ('Foo.method')
20 MAKE_FUNCTION 0
22 STORE_NAME 4 (method)
24 LOAD_CONST 5 (None)
26 RETURN_VALUE
__init__メソッドの定義、methodメソッドの定義はさらに「ク...
>>> dis.dis(co.co_consts[0].co_consts[1])
4 0 LOAD_FAST 1 (x)
2 LOAD_FAST 0 (self)
4 STORE_ATTR 0 (x)
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
>>> dis.dis(co.co_consts[0].co_consts[3])
7 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (self)
4 LOAD_ATTR 1 (x)
6 CALL_FUNCTION 1
8 POP_TOP
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
ところでそれぞれのco_namesを見てみましょう。
>>> co.co_consts[0].co_consts[1].co_names
('x',)
>>> co.co_consts[0].co_consts[3].co_names
('print', 'x')
selfはいません。引数(と今回はないけどローカル変数)はco_...
>>> co.co_consts[0].co_consts[1].co_varnames
('self', 'x')
>>> co.co_consts[0].co_consts[3].co_varnames
('self',)
なお、1番目(__init__メソッドに対応するコードオブジェクト...
しれっとローカル変数と書きましたがトップレベルの変数(foo...
*おわりに [#mec2a46e]
今回はとりあえず手始めにクラス定義がどのようなバイトコー...
ところで、もちろんdisモジュールで出てくるのはPython処理系...
ページ名: