Как мне скопировать ** kwargs на себя? - PullRequest
16 голосов
/ 29 марта 2010

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

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

class ValidationRule:
    def __init__(self, **kwargs):
        # code to assign **kwargs to .self

Ответы [ 7 ]

21 голосов
/ 29 марта 2010

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

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.

14 голосов
/ 29 марта 2010

Возможно, это не самый чистый способ, но он работает:

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

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

12 голосов
/ 29 марта 2010

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

class ValidationRule:
   def __init__(self, **kwargs):
      for (k, v) in kwargs.items():
         setattr(self, k, v)
4 голосов
/ 29 марта 2010
class ValidationRule:
   def __init__(self, **kwargs):
      self.__dict__.update(kwargs)
2 голосов
/ 28 октября 2015

Это можно считать более приятным, чем обновление __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'
2 голосов
/ 29 марта 2010

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

class ValidationRule:
   def __init__(self, **kwargs):
       self.__dict__.update(kwargs)
0 голосов
/ 18 января 2012

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

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'
...