美國哲學家約翰‧羅傑斯‧希爾勒 John Rogers Searle 早年提出人類一般的『 Speech acts 』言語行為,除了『字面意義』外,通常還有『言外之意』。比方不同的『句型』的整體意義不同,即使其中的文字相同︰
李四真是好人。
李四真是好人?
李四,真是好人!
當然更無需要說『聲調』之『抑揚頓挫』的作用了。因為人們的『言談』一般是擁有『目的性』的,於是『用字遣詞』常具有言外之『意圖性』,就像有時禮貌上『不方便』講的,所以也就只能『假借』的說了。
─── 《人工智慧!!》
一個語言之字詞意義表達力及其符號語法的方便性,是兩回事也。舉例而言,在派生裡『列印』、『賦值』、『輸入』能否用一句話來寫?
rock64@rock64:~ python3 Python 3.5.3 (default, Sep 27 2018, 17:25:39) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print(x = input("var?")) var?10 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'x' is an invalid keyword argument for this function >>>
假使拗口寫成︰
怕不清楚 function scope 者︰
PEP 3104 — Access to Names in Outer Scopes
Abstract
In most languages that support nested scopes, code can refer to or rebind (assign to) any name in the nearest enclosing scope. Currently, Python code can refer to a name in any enclosing scope, but it can only rebind names in two scopes: the local scope (by simple assignment) or the module-global scope (using a global declaration).
This limitation has been raised many times on the Python-Dev mailing list and elsewhere, and has led to extended discussion and many proposals for ways to remove this limitation. This PEP summarizes the various alternatives that have been suggested, together with advantages and disadvantages that have been mentioned for each.
那個『』之語境費思量呦。
縱使熟讀 dispy 原始碼三百行,而且知道如何
Writing a Disassembler
Given all this information, we’re now more than set to write our own little bytecode disassembler. We’ll simply take a bytestring, such as returned by a code object’s co_code
attribute, and loop through it’s bytes. We’ll have to read the bytes to decode instructions and pick out the right number of subsequent bytes for arguments. Also, we’ll want to make use of co_lnotab
andco_firstlineno
to cross-reference between the bytecode and the original, disassembled code. You can find a small implementation (~300 lines) following these ideas here.
※ 註︰
/dispy
A tiny Python bytecode disassembler
dispy
A tiny Python bytecode disassembler.
dispy
emulates the behavior of dis.dis
in that it will take a function, method, code object or code string and print a pretty representation of the corresponding bytecode. See here for a blog post on dis.dis
and bytecode in general.
Usage
To use dispy
, simply import the package and call the dispy.dis()
method with any of the aforementioned argument types. For example:
def foo(): a = 1 b = 2 return math.tanh(a * b) dispy.dis(foo)
will print:
0 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (a) 1 6 LOAD_CONST 2 (2) 9 STORE_FAST 1 (b) 2 12 LOAD_GLOBAL 0 (math) 15 LOAD_ATTR 1 (tanh) 18 LOAD_FAST 0 (a) 21 LOAD_FAST 1 (b) 24 BINARY_MULTIPLY 25 CALL_FUNCTION 26 POP_TOP 27 STOP_CODE 28 RETURN_VALUE
※ 參考︰
git clone https://github.com/goldsborough/dispy
rock64@rock64:~ more example.py #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import math import dispy def foo(): a = 1 b = 2 return math.tanh(a * b) def main(): dispy.dis(foo) print('=' * 50) dispy.dis('a = 1; b = 2;\nc = a + b') if __name__ == '__main__': main()
rock64@rock64:~/dispy$ python3 example.py 10 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (a) 11 6 LOAD_CONST 2 (2) 9 STORE_FAST 1 (b) 12 12 LOAD_GLOBAL 0 (math) 15 LOAD_ATTR 1 (tanh) 18 LOAD_FAST 0 (a) 21 LOAD_FAST 1 (b) 24 BINARY_MULTIPLY 25 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 28 RETURN_VALUE ================================================== 1 0 LOAD_CONST 0 (1) 3 STORE_NAME 0 (a) 1 6 LOAD_CONST 1 (2) 9 STORE_NAME 1 (b) 1 12 LOAD_NAME 0 (a) 15 LOAD_NAME 1 (b) 18 BINARY_ADD 19 STORE_NAME 2 (c) 22 LOAD_CONST 2 (None) 25 RETURN_VALUE
切莫以有得為喜︰
山外有山,尚須專研︰
俗話說︰
萬丈高樓平地起。千仞之山土石積。
學習之道
真積力,久則入。