2014-09-20 10 views
0

У меня проблема решена, но я хотел бы знать, почему.Динамически изменяющие атрибуты экземпляра

Моя ситуация выглядит следующим образом:

Я определил класс Vector как:

class Vector: 
    def __init__(self, x=0, y=0): 
     self.x = x 
     self.y = y 

И следующий экземпляр, созданный:

v1 = Vector(1,1) 

Почему следующий код не работает

def plus_one_A(thing): 
    attrs = vars(thing) 
    for attr_name, value in attrs.items(): 
     if type(value) == int or type(value) == float:     
      eval('thing.'+ attr_name + ' += 1') 
    return thing 

v2 = plus_one_A(v1) 

thing.x += 1 
     ^
SyntaxError: invalid syntax 

Но следующее ли?

def plus_one_B(thing): 
    attrs = vars(thing) 
    for attr_name, value in attrs.items(): 
     if type(value) == int or type(value) == float:     
      setattr(thing, attr_name, value + 1) 
    return thing 

v2 = plus_one_B(v1) 

Не предполагается, что эти коды эквивалентны?

ответ

1

Вам необходимо использовать exec вместо eval. eval может использоваться только для expression, а не statement.

>>> eval('1 + 2') 
3 
>>> eval('x = 1 + 2') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<string>", line 1 
    x = 1 + 2 
    ^
SyntaxError: invalid syntax 
>>> 
>>> exec('x = 1 + 2') 
>>> x 
3 

BTW, isinstance не только принимать объект типа, но и принять кортеж типов для второго параметра.

>>> isinstance(1, (int, float)) 
True 
>>> isinstance(1.0, (int, float)) 
True 
>>> isinstance('1', (int, float)) 
False 
+0

Эй, отличный ответ !. Это было то, чего мне не хватало, теперь я знаю разницу между 'exec()' и 'eval()' (я думал, что они одинаковые, но я должен был предположить, что в Python 'должен быть один - и желательно только один - простой способ сделать это). Большой совет о 'isinstance()' BTW – llekn