изменить setattr на mass — присвоить нескольким атрибутам разные значения

#python

#python

Вопрос:

Я пытался создать класс, который может присваивать несколько атрибутов разным значениям за один раз. Итак, я попытался изменить setattr для этого.

 class hello():
    def __setattr__(self,attr,value):
        if type(attr) == str:
            self.__dict__[attr] = value
        elif type(attr) == list:
            for item,val in zip(attr,value):
                self.__dict__[item] = val
        else:
            print "Error!!!"
  

чтобы мой желаемый класс имел свойство:

 >>> hola = hello()
>>> setattr(hola,["a","b"],[1,2])
>>> hola.a
1
>>> hola.b
2
  

Но выполнение этого возвращает

 TypeError: attribute name must be string, not 'list'
  

Это правда, что я могу определить специальный метод внутри класса для этой работы, например

 def assigner(self, attrlist, valuelist):
    for item,value in zip(attrlist,valuelist):
        self.__dict__[item] = value
  

Но хотелось бы знать, почему это невозможно с помощью setattr и наиболее эффективного способа выполнения этой работы

Комментарии:

1. if type(attr) == str: вы не должны делать это для проверки типов. Используйте isinstance вместо этого: if isinstance(attr, str): . Также обратите внимание: вместо того, чтобы устанавливать атрибуты один за другим в __dict__ , вы могли бы сделать : self.__dict__.update(zip(attrlist, valuelist)) . Это более эффективно, чем делать это вручную.

Ответ №1:

Из документации по setattr функции:

Аргументами являются объект, строка и произвольное значение.

Второй аргумент должен быть str .

Возможным обходным путем является определение __setitem__ вместо __setattr__

 class hello():
    def __setitem__(self, k, v):
        self.__dict__.update(zip(k, v) if type(k) is tuple else [(k, v)])
  

Это позволит вам присваивать значения в dict стиле

 In [2]: heya = hello()

In [3]: heya['a', 'b'] = [1, 2]

In [4]: heya.a
Out[4]: 1

In [5]: heya.b
Out[5]: 2
  

Тем не менее, ничто не мешает вам назначать их так

 In [15]: heya.a, heya.b = [1, 2]
  

Ответ №2:

Ну TypeError , это довольно хорошо сказано: имя (второй аргумент) должно быть строкой, а не списком.

Аргументами являются объект, строка и произвольное значение

https://docs.python.org/2/library/functions.html#setattr