What is the best way to define a class method __init__ with optional keyword arguments?

I want the class to do the following:

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

      

But it looks sloppy to me. Is there a better way to define this __ init __ method ? I would like all keyword arguments to remain optional.

+3


source to share


6 answers


If you only have 3 arguments then Bhargav Rao's solution is more appropriate, but if you have a lot of potential arguments try:

class Player:
    def __init__(self, **kwargs):
        self.last_name = kwargs.get('last_name')
        # .. etc.

      

kwargs.get('xxx')

will return the key xxx

if it exists and return None if it doesn't. .get

takes an optional second argument which is returned if xxx

not in kwargs

(instead of None

), eg. to set an attribute to an empty string use kwargs.get('xxx', "")

.



If you really want the attribute to be undefined, if it is not in kwargs

, then it will do this:

class Player:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

      

would be awesome behavior, so I suggest not doing it this way.

+10


source


If you only have 3 keywords, then this is better.



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

      

+11


source


You can use 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

      


With arguments ** 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


source


Here's one way to do it, so it's easy to change:

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

      

Sample usage:

Player(last_name="George", attitude="snarky")

      

Results:

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'

      

+3


source


May I try this way:

#!/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

      

Output:

First
Last
First

      

0


source


It depends on the end result you want. If you want to create a class where attributes are defined in a dictionary, you can use 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'

      

0


source







All Articles