【发布时间】:2017-04-01 09:36:14
【问题描述】:
在 Python2 和 Python3 中,堆栈跟踪中不使用函数的 __name__,而是使用原始名称(在 def 之后指定的名称)。
考虑这个例子:
import traceback
def a():
return b()
def b():
return c()
def c():
print("\n".join(line.strip() for line in traceback.format_stack()))
a.__name__ = 'A'
b.__name__ = 'B'
c.__name__ = 'C'
a();
输出是:
File "test.py", line 16, in <module>
a();
File "test.py", line 4, in a
return b()
File "test.py", line 7, in b
return c()
File "test.py", line 10, in c
print("\n".join(line.strip() for line in traceback.format_stack()))
为什么会这样?如何更改堆栈跟踪中使用的名称?那么__name__ 属性在哪里使用呢?
【问题讨论】:
-
a.__name__ 似乎是 a.func_name 的别名。堆栈跟踪似乎都没有使用它们。
-
函数的代码对象也存储名称,但该属性是只读的。我认为这是回溯中使用的属性。要更改该名称,您需要从其属性重新创建代码对象并将其分配回函数对象的代码属性。见stackoverflow.com/questions/16064409/…
-
这很有趣 - 看起来它使用的是代码对象的名称
a.__code__.co_name,而不是函数对象的名称。 -
@hivert
func_name确实是一个__name__别名,有明确记载:docs.python.org/2/library/inspect.html -
@DanD。我什至可以用动态名称创建新函数,但我不知道该怎么做(保存
eval)