What is a better way to define a class' __init__ method with optional keyword arguments?
我想让全班同学做同样的事情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Player: def __init__(self, **kwargs): try: self.last_name = kwargs['last_name'] except: pass try: self.first_name = kwargs['first_name'] except: pass try: self.score = kwargs['score'] except: pass |
但我觉得这很马虎。有没有更好的方法来定义这个初始化方法?我希望所有关键字参数都保持可选。
如果您只有3个关键字参数,那么这会更好。
1 2 3 4 5 6 | class Player: def __init__(self, last_name=None, first_name=None, score=None): self.last_name = last_name self.first_name = first_name self.score = score |
。
如果您只有3个参数,那么Bhargav Rao的解决方案更合适,但是如果您有很多潜在参数,请尝试:
1 2 3 4 | class Player: def __init__(self, **kwargs): self.last_name = kwargs.get('last_name') # .. etc. |
如果您真的希望属性未定义,如果它不在
1 2 3 4 | class Player: def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) |
号
这将是令人惊讶的行为,所以我建议不要这样做。
有一种方法可以很容易地进行更改:
1 2 3 4 5 6 7 8 9 10 | class Player: _VALID_KEYWORDS = {'last_name', 'first_name', 'score'} def __init__(self, **kwargs): for keyword, value in kwargs.items(): if keyword in self._VALID_KEYWORDS: setattr(self, keyword, value) else: raise ValueError( "Unknown keyword argument: {!r}".format(keyword)) |
。
样品用途:
1 | Player(last_name="George", attitude="snarky") |
号
结果:
1 2 3 4 5 6 | Traceback (most recent call last): File"keyword_checking.py", line 13, in <module> Player(last_name="George", attitude="snarky") File"keyword_checking.py", line 11, in __init__ raise ValueError("Unknown keyword argument: {!r}".format(keyword)) ValueError: Unknown keyword argument: 'attitude' |
号
可以使用关键字参数:
1 2 3 4 5 6 7 8 9 | class Player: def __init__(self, last_name=None, first_name=None, score=None): self.last_name = last_name self.first_name = first_name self.score = score obj = Player('Max', 'Jhon') print obj.first_name, obj.last_name |
1 | Jhon Max |
。
带参数**Kwargs
1 2 3 4 5 6 7 8 9 10 11 12 | class Player: def __init__(self, **args): self.last_name = args.get('last_name') self.first_name = args.get('first_name') self.score = args.get('score', 0) # 0 is the default score. obj = Player(first_name='Max', last_name='Jhon') print obj.first_name, obj.last_name, obj.score |
1 | Max Jhon 0 |
。
这取决于你想要的最终结果。如果您想创建一个类,在字典中定义属性,那么可以使用setattr。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Player: def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) In [1]: player = Player(first_name='john', last_name='wayne', score=100) In [2]: player.first_name Out[2]: 'john' In [3]: player.last_name Out[3]: 'wayne' In [4]: player.score Out[4]: 100 In [5]: player.address --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-6-0f7ee474d904> in <module>() ----> 1 player.address AttributeError: 'Player' object has no attribute 'address' |
我能试试这个方法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/python class Player(object): def __init__(self, **kwargs): for key, val in kwargs.items(): self.__dict__[key] = val obj = Player(first_name='First', last_name='Last') print obj.first_name print obj.last_name newobj = Player(first_name='First') print newobj.first_name |
输出:
1 2 3 | First Last First |
。