Python解釋器簡介(2):代碼對象
這是Python解釋器簡介的第二部分。***部分請點擊這里 。
完成編譯之前的三個步驟都是在檢查一個簡單的函數對象。我們現在來談談更深層次的對象——函數的代碼對象。
- >>> 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>
從上面的代碼,你能發現所謂的代碼對象就是函數對象的一個屬性。(這個函數對象還有許多其它的屬性,但它們大多都很無聊,因為 foo 函數實在是太簡單了。)
代碼對象是在Python編譯器中生成的,并且在解釋器中完成解釋工作。它向解釋器傳遞“開工了”的信息。我們再來看看代碼對象的屬性。
- >>> 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']
這個屬性列表雖然很長,但是其中大多數屬性我們今天并不會涉及。我們只關注3個有趣的 foo 函數代碼對象的屬性。
- >>> foo.func_code.co_varnames
- ('a', 'x')
- >>> foo.func_code.co_consts
- (None, 3)
- >>> foo.func_code.co_argcount
- 1
通過調用它們,我們能依次得到:變量名、函數中已知的常量和函數參數的數量。但是目前為止,我們還是不知道生成代碼對象的指令到底是什么。事實上,這個指令叫做字節碼。字節碼也是代碼對象的一個屬性:
- >>> foo.func_code.co_code
- 'd\x01\x00}\x01\x00|\x01\x00|\x00\x00\x17S'
我們得到了許多待分解的信息。這里到底發生了什么?在下一部分,我們將深入研究字節碼。