请考虑以下函数定义,其中异常名称e
隐藏参数:
def f(a,e):
try:
raise RuntimeError('test')
except RuntimeError as e:
pass
在函数f
的符号表中,我期望三个符号:两个参数a,e
(未分配(和一个已分配的本地e
。但是符号表包含两个符号:参数a
(尚未分配(和参数e
(已分配(。似乎未分配参数e
的属性和异常名称e
组合成一个符号。这有意义吗?
请参阅以下测试代码:
import symtable
def symStat(sym):
stat = []
if sym.is_parameter(): stat.append('param')
if sym.is_assigned(): stat.append('assigned')
if sym.is_referenced(): stat.append('referenced')
return stat
INDENT_STR = ' '
def printSymsRec(st, indentLevel=0):
indent = indentLevel*INDENT_STR
print('%s%s:' % (indent, st.get_name()),
[(sym.get_name(), symStat(sym)) for sym in st.get_symbols()])
for stc in st.get_children():
printSymsRec(stc, indentLevel+1)
TEST_CODE = """
def f(a,e):
try:
raise RuntimeError('test')
except RuntimeError as e:
pass
""".strip()
symRoot = symtable.symtable(TEST_CODE, "<string>", "exec")
printSymsRec(symRoot)
它给出了以下输出:
top: [('f', ['assigned'])]
f: [('a', ['param']), ('e', ['param', 'assigned']), ('RuntimeError', ['referenced'])]
为什么输出不像下面:
...
f: [('a', ['param']), ('e', ['param']), ('e', ['assigned']), ...]
参数在这方面并不特殊,它们就像任何其他名称一样。因此,当except RuntimeError as e
分配给e
时,它会覆盖参数的值。这不是特定于except
语句;您可以从简单的作业中获得相同的行为:
TEST_CODE = "def f(e): e = 0"
symRoot = symtable.symtable(TEST_CODE, "<string>", "exec")
printSymsRec(symRoot.get_children()[0])
# -> f: [('e', ['param', 'assigned'])]