【问题标题】:Incrementing integer using variable name string使用变量名字符串递增整数
【发布时间】:2020-03-20 04:49:59
【问题描述】:

我在 python 解释器中执行以下操作,它可以工作:

rhce=rhcsa=0
args=['rhce','rhcsa']
for cert in args:
    exec(cert+'+=1')
    print(eval(cert))

>>> 1
>>> 1

如您所见,无论您使用 print(rhce) 还是 print(eval(cert)),变量都会递增。但是,当我将完全相同的 sn-p 代码放入类函数中时,它不再起作用。不会抛出异常,但变量永远不会增加。这就像执行不工作:

def addCertUser(self,userid,args):
    rhcsa=rhce=0

    print(args)
    try:
        for cert in args:
            exec(cert+'+=1')
            print(eval(cert))
    except Exception as e:
        print(e)


>>> ['rhce', 'rhcsa']
>>> 0
>>> 0

我在这里错过了什么?

【问题讨论】:

  • 为什么需要使用eval?为什么不直接使用 dict 将名称映射到 int 值?
  • 您没有展示如何调用该函数。需要提供minimal reproducible example
  • 1.我不知道,为什么它不起作用,但使它起作用的方法是将rhcsa = rhce = 0 替换为exec("rhcsa = rhce = 0") 2。正如@ChrisDoyle 所提到的,在生产代码中使用 eval 和 exec 确实是一种不好的做法,您可能需要使用以下内容:pastebin.com/PTV5SAbd

标签: python-3.x exec


【解决方案1】:

评估或执行代码从来都不是一个好主意,100 次中有 99 次有更好的方法来做到这一点。在这种情况下,除非您有任何其他真正需要使用 eval 和 exec 的原因,否则您可以使用 dict 实现您的尝试。它可以保存一个键(“名称”),用于非常安全地引用或查找您的值。

class MyClass:
    def __init__(self):
        self.my_counts = {
            'rhce': 0,
            'rhcsa': 0
        }
    def add_cert_user(self, userid, args):
        print("start of function", self.my_counts)
        for cert in args:
            if cert  in self.my_counts:
                self.my_counts[cert] += 1
        print("end of function", self.my_counts)

me = MyClass()
args = ['rhce','rhcsa']
me.add_cert_user("test", args)
me.add_cert_user("test", args)
me.add_cert_user("test", args)

输出

start of function {'rhce': 0, 'rhcsa': 0}
end of function {'rhce': 1, 'rhcsa': 1}
start of function {'rhce': 1, 'rhcsa': 1}
end of function {'rhce': 2, 'rhcsa': 2}
start of function {'rhce': 2, 'rhcsa': 2}
end of function {'rhce': 3, 'rhcsa': 3}

【讨论】:

    【解决方案2】:

    获得不同结果的原因是您尝试动态修改的变量的范围在两个示例之间发生了变化,从模块级范围变为局部函数范围。

    使用 exec 修改局部变量并不能保证任何结果,正如您在 exec 函数的文档中所见,应避免使用。

    查看另一个详细回复herehere

    【讨论】:

      猜你喜欢
      • 2019-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      相关资源
      最近更新 更多