我们如何查看 python 源代码的符号表?
我的意思是,Python 在实际运行之前为每个程序制作了一个符号表。所以我的问题是如何将该符号表作为输出?
我们如何查看 python 源代码的符号表?
我的意思是,Python 在实际运行之前为每个程序制作了一个符号表。所以我的问题是如何将该符号表作为输出?
Python本质上是动态的而不是静态的。与编译的目标代码中的符号表不同,虚拟机有一个可寻址的变量命名空间。
dir()
or函数返回代码中该dir(module)
点的有效命名空间。它主要用于交互式解释器,但也可以被代码使用。它返回一个字符串列表,每个字符串都是一个带有一些值的变量。
该globals()
函数将变量名称的字典返回到变量值,此时变量名称在范围内被认为是全局的。
该locals()
函数将变量名称的字典返回到变量值,此时变量名称在范围内被认为是本地的。
$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> import base64
>>> dir(base64)
['EMPTYSTRING', 'MAXBINSIZE', 'MAXLINESIZE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_b32alphabet', '_b32rev', '_b32tab', '_translate', '_translation', '_x', 'b16decode', 'b16encode', 'b32decode', 'b32encode', 'b64decode', 'b64encode', 'binascii', 'decode', 'decodestring', 'encode', 'encodestring', 'k', 're', 'standard_b64decode', 'standard_b64encode', 'struct', 'test', 'test1', 'urlsafe_b64decode', 'urlsafe_b64encode', 'v']
如果您询问生成字节码时使用的符号表,请查看symtable
模块。此外,Eli Bendersky 的这两篇文章引人入胜,而且非常详细:
在第 2 部分中,他详细介绍了一个可以打印出符号表描述的函数,但它似乎是为 Python 3 编写的。这是 Python 2.x 的版本:
def describe_symtable(st, recursive=True, indent=0):
def print_d(s, *args):
prefix = ' ' *indent
print prefix + s + ' ' + ' '.join(args)
print_d('Symtable: type=%s, id=%s, name=%s' % (
st.get_type(), st.get_id(), st.get_name()))
print_d(' nested:', str(st.is_nested()))
print_d(' has children:', str(st.has_children()))
print_d(' identifiers:', str(list(st.get_identifiers())))
if recursive:
for child_st in st.get_children():
describe_symtable(child_st, recursive, indent + 5)
您可能会喜欢 Eli Bendersky 在这里就该主题撰写的文章
在 CPython 中,您可以使用该symtable
模块。
在第 2 部分中,Eli 描述了一种遍历符号表的方法,该方法非常有用:
def describe_symtable(st, recursive=True, indent=0):
def print_d(s, *args):
prefix = ' ' * indent
print(prefix + s, *args)
assert isinstance(st, symtable.SymbolTable)
print_d('Symtable: type=%s, id=%s, name=%s' % (
st.get_type(), st.get_id(), st.get_name()))
print_d(' nested:', st.is_nested())
print_d(' has children:', st.has_children())
print_d(' identifiers:', list(st.get_identifiers()))
if recursive:
for child_st in st.get_children():
describe_symtable(child_st, recursive, indent + 5)