python:按名称分配属性值

python: assign attribute value by name

作为 python3 中一个更大项目的一部分,我需要一种本着以下(无效)代码精神的方法:

class Qclass:
     def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

def increment(Q, var):
    eval('Q.{} = Q.{} + 100'.format(var,var))

Q = Qclass(1,2,3)
increment(Q,'a')
print(Q.a)
>>> 101

我需要这个,因为我不知道 Q 的哪个属性必须递增。一个解决方案是为每个属性声明特定的函数并使用一些选择器,但我希望尽可能避免这种情况。

有没有一种简洁的方法可以做到这一点?

setattr and getattr 的组合可以:

def increment(Q, var):
    setattr(Q, var, getattr(Q, var) + 100)

在您的代码段执行后 Q.a 产生 101

getattr 只是通过给定名称从对象中获取一个属性(如果该属性不存在,则允许使用默认值);类似于 Q.<val_name>

setattr 执行赋值,在对象上设置具有给定名称的属性。

您可以使用 build-in 函数 vars 其中 returns 在给定范围内声明的变量字典。它的用法如下所示:

Q = Qclass(1,2,3)
try:
    vars(Q)['a'] += 1
except KeyError:
    Q.a = 1

非常糟糕的主意使用eval(..)(几乎在任何情况下)。您可以使用更安全的 getattr(..)setattr(..)

def increment(Q, var):
    setattr(Q,var,getattr(Q,var)+100)

getattr(obj,name)setattr(obj,name,val) 获取和设置 object 的属性。所以在这里你可以 get/set 如果你事先不知道名称的属性。

所以结果代码是:

class Qclass:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

def increment(Q, var):
    setattr(Q,var,getattr(Q,var)+100)

Q = Qclass(1,2,3)
increment(Q,'a')
print(Q.a)