使用可选关键字参数定义类的 __init__ 方法的更好方法是什么?
What is a better way to define a class' __init__ method with optional keyword arguments?
我希望 class 执行与以下相同的操作:
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
但这对我来说真的很草率。有没有更好的方法来定义这个__init__方法?我希望所有关键字参数都保持可选。
如果你只有 3 个参数,那么 Bhargav Rao 的解决方案更合适,但如果你有很多潜在的参数,那么试试:
class Player:
def __init__(self, **kwargs):
self.last_name = kwargs.get('last_name')
# .. etc.
kwargs.get('xxx')
将 return xxx
键(如果存在),return None(如果不存在)。 .get
采用可选的第二个参数,如果 xxx
不在 kwargs
中(而不是 None
),则该参数被 returned,例如将属性设置为空字符串使用 kwargs.get('xxx', "")
.
如果您真的希望属性在 kwargs
中未定义,则可以这样做:
class Player:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
这将是令人惊讶的行为,所以我建议不要这样做。
您可以使用 keyword arguments:
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
Jhon Max
带参数**kwargs
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
Max Jhon 0
如果你只有3个关键字args,那就更好了。
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
我可以这样试试吗:
#!/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
输出:
First
Last
First
这取决于你想要的最终结果。如果你想创建一个 class 属性在字典中定义的地方,你可以使用 setattr.
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'
这是一种可以轻松更改的方法:
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))
示例用法:
Player(last_name="George", attitude="snarky")
结果:
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'
我希望 class 执行与以下相同的操作:
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
但这对我来说真的很草率。有没有更好的方法来定义这个__init__方法?我希望所有关键字参数都保持可选。
如果你只有 3 个参数,那么 Bhargav Rao 的解决方案更合适,但如果你有很多潜在的参数,那么试试:
class Player:
def __init__(self, **kwargs):
self.last_name = kwargs.get('last_name')
# .. etc.
kwargs.get('xxx')
将 return xxx
键(如果存在),return None(如果不存在)。 .get
采用可选的第二个参数,如果 xxx
不在 kwargs
中(而不是 None
),则该参数被 returned,例如将属性设置为空字符串使用 kwargs.get('xxx', "")
.
如果您真的希望属性在 kwargs
中未定义,则可以这样做:
class Player:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
这将是令人惊讶的行为,所以我建议不要这样做。
您可以使用 keyword arguments:
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
Jhon Max
带参数**kwargs
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
Max Jhon 0
如果你只有3个关键字args,那就更好了。
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
我可以这样试试吗:
#!/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
输出:
First
Last
First
这取决于你想要的最终结果。如果你想创建一个 class 属性在字典中定义的地方,你可以使用 setattr.
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'
这是一种可以轻松更改的方法:
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))
示例用法:
Player(last_name="George", attitude="snarky")
结果:
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'