Python解釋器簡(jiǎn)介(2):代碼對(duì)象
這是Python解釋器簡(jiǎn)介的第二部分。***部分請(qǐng)點(diǎn)擊這里 。
完成編譯之前的三個(gè)步驟都是在檢查一個(gè)簡(jiǎn)單的函數(shù)對(duì)象。我們現(xiàn)在來談?wù)劯顚哟蔚膶?duì)象——函數(shù)的代碼對(duì)象。
- >>> def foo(a):
- ... x = 3
- ... return x + a
- ...
- >>> foo
- <function foo at 0x107ef7aa0>
- >>> foo.func_code
- <code object foo at 0x107eeccb0, file "<stdin>", line 1>
從上面的代碼,你能發(fā)現(xiàn)所謂的代碼對(duì)象就是函數(shù)對(duì)象的一個(gè)屬性。(這個(gè)函數(shù)對(duì)象還有許多其它的屬性,但它們大多都很無聊,因?yàn)?foo 函數(shù)實(shí)在是太簡(jiǎn)單了。)
代碼對(duì)象是在Python編譯器中生成的,并且在解釋器中完成解釋工作。它向解釋器傳遞“開工了”的信息。我們?cè)賮砜纯创a對(duì)象的屬性。
- >>> dir(foo.func_code)
- ['__class__', '__cmp__', '__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_lnotab', 'co_name', 'co_names', 'co_nlocals',
- 'co_stacksize', 'co_varnames']
這個(gè)屬性列表雖然很長(zhǎng),但是其中大多數(shù)屬性我們今天并不會(huì)涉及。我們只關(guān)注3個(gè)有趣的 foo 函數(shù)代碼對(duì)象的屬性。
- >>> foo.func_code.co_varnames
- ('a', 'x')
- >>> foo.func_code.co_consts
- (None, 3)
- >>> foo.func_code.co_argcount
- 1
通過調(diào)用它們,我們能依次得到:變量名、函數(shù)中已知的常量和函數(shù)參數(shù)的數(shù)量。但是目前為止,我們還是不知道生成代碼對(duì)象的指令到底是什么。事實(shí)上,這個(gè)指令叫做字節(jié)碼。字節(jié)碼也是代碼對(duì)象的一個(gè)屬性:
- >>> foo.func_code.co_code
- 'd\x01\x00}\x01\x00|\x01\x00|\x00\x00\x17S'
我們得到了許多待分解的信息。這里到底發(fā)生了什么?在下一部分,我們將深入研究字節(jié)碼。