Python 如何将**kwargs复制到self?

Python 如何将**kwargs复制到self?,python,syntax,constructor,keyword-argument,Python,Syntax,Constructor,Keyword Argument,是否有一种方法可以定义\uuuu init\uuuu以便将**kwargs中定义的关键字分配给类 例如,如果我要使用ValidationRule(other='email')初始化ValidationRule类,则应将self.other的值添加到类中,而无需显式命名每个可能的kwarg class ValidationRule: def __init__(self, **kwargs): # code to assign **kwargs to .self 你可以这样

是否有一种方法可以定义
\uuuu init\uuuu
以便将
**kwargs
中定义的关键字分配给类

例如,如果我要使用
ValidationRule(other='email')
初始化
ValidationRule
类,则应将
self.other
的值添加到类中,而无需显式命名每个可能的kwarg

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

你可以这样做:

class ValidationRule:
   def __init__(self, **kwargs):
      for (k, v) in kwargs.items():
         setattr(self, k, v)
我想我见过这样的解决办法。不管怎样,它可以看起来像:

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)

此类将只接受在
\u allowed

中列出的具有白名单属性名称的参数。这可能不是最干净的方法,但它可以工作:

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

我想我更喜欢它,因为它限制了可用属性,以便在您的输入来自外部源时避免麻烦。

您可以通过更新实例的
\u dict\u
属性来设置
kwargs
参数

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

我发现上面的答案很有帮助,然后经过改进:

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(key4=4)
TypeError: __init__() got an unexpected keyword argument 'key4'

这可以被认为比更新
\uuuu dict\uuuu
更好:

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

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

你不使用新式课程有什么原因吗?@Georg:我甚至不知道什么是新式课程?如果相关的话,我使用的是Python 2.5。要创建newstyle类,您只需要从newstyle类(通常是
对象
)继承,所以使用
类验证规则(对象):
更多信息:newstyle。。?似乎是python3的老风格?这在那里还能用吗?ValidationRule只是我的基类,它没有任何自己的属性,因此它们不会意外地覆盖任何内容,但否则,这将是一个很好的安全防护;)在这种情况下,我可能会使用黑名单而不是白名单,以避免对它们进行太多限制。Python-3重命名为
dict.iteritems->dict.items
,我不知道这是否是python3的问题,但在python3.8中发送无效的
kwargs
会引发
AssertionError
。我用
尝试…捕捉
来克服this@Mr.Hobo,您应该能够看到断言的来源,并且很可能它会导致行
assert(self.\uuuuu class\uuuuuu.\uuuu允许使用k)
,这是关于验证的答案的最后一句话,它是它的唯一角色;)也就是说,如果您不喜欢它,可以将其删除,或者用不同的处理方法替换。如果kwargs列表很长,您可能希望使用iteritems()而不是items()。不过出于您的目的,这应该没问题。@GeorgSchölly
iteritems()
items()
之间有什么区别?@StevenVascellaro在Python 2中
iteritems()
,返回一个生成器,而
items()
返回一个列表。在Python 3中,
items()
返回一个itemview,并且
iteritems()
被删除。我更喜欢
items()
,因为它两者都兼容。对于非常大的dict,我仍然使用
iteritems()
。另请参见,如果变量是“魔法”变量,它将无法正常工作。考虑和。这适用于Python2和Python3。
class C:
    def __init__(self, **kwargs):
        vars(self).update(kwargs)

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