Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как скопировать **kwargs себе?

Автор вопроса: mpenОтветов: 6

Есть ли способ определить __init__, чтобы ключевые слова, определенные в **kwargs, были назначены классу?

Например, если бы мне нужно было инициализировать класс ValidationRule с помощью ValidationRule(other='email'), значение для self.other должно быть добавлено к классу без необходимости явно называть все возможные kwarg.

class ValidationRule:
    def __init__(self, **kwargs):
        # code to assign **kwargs to .self
  • Есть ли причина, по которой вы не используете классы нового стиля? Georg Schölly 29.03.2010
  • @Georg: я даже не знаю, что такое классы нового стиля? Я использую Python 2.5, если это уместно. mpen 29.03.2010
  • Чтобы создать класс нового стиля, вам просто нужно наследоваться от класса нового стиля (обычно object), поэтому используйте class ValidationRule(object): Подробнее здесь: python.org/doc/newstyle John La Rooy 29.03.2010
  • Новый стиль..? кажется старым стилем в python3? это вообще там будет работать? holms 06.10.2015

pythonconstructorsyntaxkeyword-argument

Ответы

Ответ 1 · рейтинг 20 · Gabe

Это может быть не самый чистый способ, но он работает:

class ValidationRule:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

Я думаю, что предпочитаю решение ony, потому что оно ограничивает доступные свойства, чтобы вы не проблемы, когда ваш вход поступает из внешних источников.

Ответ 2 · рейтинг 30 · ony

Я думаю, что где-то в stackoverflow я видел такое решение. В любом случае это может выглядеть так:

class ValidationRule:
    __allowed = ("other", "same", "different")
    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
            assert( k in self.__class__.__allowed )
            setattr(self, k, v)

Этот класс будет принимать только аргументы с именами атрибутов из белого списка, перечисленными в __allowed.

Ответ 3 · рейтинг 12 · sth

Вы можете сделать что-то вроде этого:

class ValidationRule:
   def __init__(self, **kwargs):
      for (k, v) in kwargs.items():
         setattr(self, k, v)

Ответ 4 · рейтинг 3 · Ruslan Spivak

Вы можете установить аргументы kwargs, обновив атрибут __dict__ экземпляра.

class ValidationRule:
   def __init__(self, **kwargs):
       self.__dict__.update(kwargs)

Ответ 5 · рейтинг 2 · Greg

Это можно считать более приятным, чем обновление __dict__:

class C:
    def __init__(self, **kwargs):
        vars(self).update(kwargs)

>>> c = C(a='a', b='b')
>>> c.a   # returns 'a'
>>> c.b   # returns 'b'

Ответ 6 · user394430

Я нашел приведенные выше ответы полезными, а затем уточнил:

class MyObj(object):
    def __init__(self, key1=1, key2=2, key3=3):
        for (k, v) in locals().iteritems():
            if k != 'self':
                setattr(self, k, v)

Контрольная работа:

>>> myobj = MyObj(key1=0)
>>> print myobj.key1
0

И валидация тоже есть:

>>> myobj = MyObj(key4=4)
TypeError: __init__() got an unexpected keyword argument 'key4'

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы