考虑以下函数定义,其中异常名称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']), ...]发布于 2020-02-10 03:27:10
在这一点上,参数并不特殊,它们就像其他名称一样。因此,当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'])]https://stackoverflow.com/questions/60140337
复制相似问题