2017-02-09 119 views
2

分配属性值作为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的哪个属性必须增加。解决方法是为每个属性声明特定的函数并使用某个选择器,但如果可能的话,我宁愿避免这种情况。

有没有一种整洁的方式来做到这一点?

+0

的[?您如何编程设置了一个Python属性(可能的复制http://stackoverflow.com/questions/285061/how-do-you-以编程方式设置属性在python) –

回答

3

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

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

getattr(obj,name)setattr(obj,name,val) get和set的obj ECT属性。因此,如果您事先不知道名称,您可以在此处设置/设置属性。

所以生成的代码是:

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) 
+0

arrr,是啊!我已经完全忘记了setattr()getattr()。谢谢。虽然你编辑我的问题把def increment()放在Qclass中吗?我的意思是它在根。 – Aderam

+0

@Aderam:那不是这个情况啊?缩进肯定有问题,因为'__init__'与'class'缩进了相同的缩进... –

+0

oups,对于错字很抱歉。 Eveything现在应该是确切的:) – Aderam

0

setattrgetattr组合会做:

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

产生101Q.a您的片段执行后。

getattr只是通过给定名称从对象获取属性(并允许在属性不存在时使用默认值);类似于Q.<val_name>

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

0

您可以使用内置函数vars,它返回在给定范围内声明的变量字典。它的用法是这样的:

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

巧妙的方法,不知道vars()。对于记录,我已经将此解决方案与setattr(Q,var,getattr(Q,var)+ 1)进行了基准对比。看起来他们在计算时间方面非常接近。谢谢 – Aderam

+0

这种方法只适用于具有'__dict__'的类,对于没有(例如使用'__slots__')的类,这不起作用。这相当于使用'Q .__ dict __ ['a'] + = 1' – mata