使用变量名字符串递增整数

Incrementing integer using variable name string

我在 python 解释器中执行以下操作并且有效:

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

>>> 1
>>> 1

如您所见,无论您使用 print(rhce) 还是 print(eval(cert)),变量都会递增。但是,当我将完全相同的代码片段放入 class 函数中时,它不再有效。没有抛出异常,但变量永远不会增加。好像 exec 不工作:

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

我在这里错过了什么?

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

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

查看另一个详细回复here and here

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

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}