为何通过`function.__code__.co_varnames`获取参数后执行eval会报错?
问题分析:eval在列表推导式中的作用域问题
示例代码
def initialize_network(n_inputs, n_hidden1, n_hidden2, n_outputs): print(eval('n_inputs')) perceptron_count = [eval(arg) for arg in initialize_network.__code__.co_varnames[:4]] initialize_network(1,2,3,4)
报错情况
- 本地运行时报错:
NameError: name 'n_inputs' is not defined - Google Colab运行时报错:
NameError: name 'n_hidden1' is not defined - 单独执行
print(eval('n_inputs'))或print(eval('n_hidden1'))可正常输出变量值
原因解析
核心问题在于列表推导式拥有独立的嵌套作用域,和函数主作用域相互隔离:
- 直接在函数内使用
eval('n_inputs')时,eval会在当前函数的局部作用域中查找变量,因此能正常获取参数值。 - 列表推导式会被Python编译成一个隐藏的嵌套函数结构,这个结构的作用域不会自动继承函数的局部变量。当你在推导式里执行
eval(arg)时,eval只能在推导式自身的作用域里查找变量,自然找不到函数的参数名,从而抛出NameError。 - 本地和Colab报错的变量名不同,只是不同环境(或Python版本)对推导式作用域变量查找顺序的实现细节差异,本质都是作用域隔离导致的问题。
修复方案
手动将函数的局部作用域传递给eval,让它能访问到函数参数:
def initialize_network(n_inputs, n_hidden1, n_hidden2, n_outputs): print(eval('n_inputs')) local_vars = locals() perceptron_count = [eval(arg, globals(), local_vars) for arg in initialize_network.__code__.co_varnames[:4]] initialize_network(1,2,3,4)
内容的提问来源于stack exchange,提问作者PhiloRobotist
相关产品推荐
相关产品推荐

