You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在类方法中使用exec赋值变量触发NameError问题求助

问题描述

在Jupyter Notebook中运行以下Python类方法代码:

def method(self, data, **kwargs):

     # parse kwargs thetas to namespace
     for theta, val in kwargs.items():
         print(theta,val)
         exec(f"{theta}={val}")

     print(kwargs)
     print(theta1,theta2)

     # ...

     return 

执行后输出如下内容并报错:

theta1 0.0001
theta2 0.0001
{'theta1': 0.0001, 'theta2': 0.0001}
NameError: name 'theta1' is not defined

原本以为exec会定义theta1、theta2等变量,尝试过添加globals()和locals()参数也无效,求原因及解决办法。

原因分析与解决方案

核心原因

Python函数(包括类方法)的本地命名空间是编译时静态确定的,exec属于动态执行代码,无法被Python的静态变量分析机制捕获,因此即使exec执行了变量赋值,函数后续也无法识别这些动态创建的变量。另外,函数内部的locals()字典是只读的,直接修改它不会同步回实际的本地命名空间,所以添加locals()参数也没用。

解决办法

不推荐用exec动态创建变量,既不安全也不符合Python编码规范,推荐以下两种更合理的方式:

  • 用字典统一存储参数
    把kwargs里的参数存到一个字典中,后续通过字典键访问:

    def method(self, data, **kwargs):
        thetas = kwargs.copy()
        print(thetas)
        print(thetas['theta1'], thetas['theta2'])
        # ...
        return
    
  • 绑定为实例属性
    如果这些参数属于类实例的属性,可以直接通过setattr绑定到self:

    def method(self, data, **kwargs):
        for theta, val in kwargs.items():
            setattr(self, theta, val)
        print(kwargs)
        print(self.theta1, self.theta2)
        # ...
        return
    
  • 若必须用exec(不推荐)
    可以通过globals()操作全局命名空间,但会污染全局变量,仅适合临时测试:

    def method(self, data, **kwargs):
        for theta, val in kwargs.items():
            exec(f"{theta}={val}", globals())
        print(kwargs)
        print(theta1, theta2)
        # ...
        return
    

内容的提问来源于stack exchange,提问作者user19976975

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:05:29