Python 定义类'__是否使用可选关键字参数初始化方法?
我希望该类执行与以下相同的操作:Python 定义类'__是否使用可选关键字参数初始化方法?,python,python-3.x,Python,Python 3.x,我希望该类执行与以下相同的操作: class Player: def __init__(self, **kwargs): try: self.last_name = kwargs['last_name'] except: pass try: self.first_name = kwargs['first_name'] except:
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
但在我看来这真的很草率。有没有更好的方法来定义这个\uuuuu init\uuuu方法?我希望所有的关键字参数都是可选的。如果您只有3个参数,那么Bhargav Rao的解决方案更合适,但是如果您有很多潜在参数,请尝试:
class Player:
def __init__(self, **kwargs):
self.last_name = kwargs.get('last_name')
# .. etc.
kwargs.get('xxx')
将返回xxx
键(如果存在),如果不存在则不返回.get
接受可选的第二个参数,如果xxx
不在kwargs
中(而不是None
),则返回该参数,例如,要将属性设置为空字符串,请使用kwargs.get('xxx',“”)
如果您确实希望该属性不在kwargs
中而不被定义,则可以这样做:
class Player:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
这将是令人惊讶的行为,因此我建议不要这样做。您可以使用:
带有参数
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
如果您只有3个关键字参数,那么这会更好
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
这取决于你想要的最终结果。如果要创建在字典中定义属性的类,可以使用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'
职业玩家:
定义初始(自我,**kwargs):
对于键,kwargs.items()中的值:
setattr(自身、键、值)
在[1]中:player=player(名字=john,姓氏=wayne,分数=100)
在[2]中:player.first_name
出[2]:“约翰”
在[3]中:player.last_name
出[3]:“韦恩”
在[4]中:player.score
Out[4]:100
在[5]中:player.address
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
在()
---->1.地址
AttributeError:“玩家”对象没有属性“地址”
这里有一种方法可以让更改变得容易:
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")
结果:
回溯(最近一次呼叫最后一次):
文件“keyword_checking.py”,第13行,在
球员(姓“乔治”,态度“斯纳基”)
文件“keyword_checking.py”,第11行,在uu init中__
raise VALUERROR(“未知关键字参数:{!r}”)。格式(关键字))
ValueError:未知的关键字参数:“态度”
您通常希望将self.score
设置为默认值,即使kwargs['score']
不可用。除(请参阅)外,不要使用毯子;除了KeyError外,最多使用,但是您仍然在硬编码名称,那么为什么要使用**kwargs
?只有3个关键字参数?然后def\uuuuu init\uuuu(self,last\u name=Null,first\u name=Null,score=Null):
@BhargavRao你应该把它作为答案发布(这是一个非常有效的答案)。@BhargavRao:Null?你在这里混淆Python的是什么语言?我已经添加了一个关于适用性的初始语句。这种方法很危险,当与kwargs中的关键字冲突时,可能会覆盖类方法。考虑添加“<代码>”、“x”、“Stulsx”、“代码”或您想分配的关键字的某种有效性,如下面的@ MaltInA@ ReLLUS所描述的,这可能是预期的语义,即类VAR是默认值,可以通过<代码>如果我今天写的话,我会把它拼成self.\uu dict\uuu.update(kw)
。我们都是成年人,所以这个方法很好。如果我想引入仅更改现有变量的限制,我会在for
-循环之前插入一行:If len(self.\uu dict)!=len(set(kwargs)| set(self.u dict_uu)):提高值错误(“…”)
@thebjorn你是对的,但我的意思是比这更深刻的影响。您可能会意外重写类方法并获得异常。这里有一个简单的例子:@redlus-well。。。那就别那么做。Python不是一种bdsm语言,它让你做了许多让bdsm语言的追随者感到厌恶的事情(!),例如,你可以分配给任何实例变量(比如a.method='blah'
)——更有趣的是,你可以将玩家实例化为p=Player(\u class\uu=NotAPlayer)
,这就是Python;-)如果你要走这条路,为什么不使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。
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")