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")