Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a better way to define a class' __init__ method with optional keyword arguments?

I want the class to do the same as 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 this looks really sloppy to me. Is there a better way to define this __init__ method? I would like all of the keyword arguments to remain optional.

like image 869
John Doh Avatar asked Jan 01 '15 16:01

John Doh


2 Answers

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

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

kwargs.get('xxx') will return the xxx key if it exists, and return None if it doesn't. .get takes an optional second argument that is returned if xxx is not in kwargs (instead of None), e.g. to set the attribute to the empty string use kwargs.get('xxx', "").

If you really want the attribute to be undefined if it isn't in the kwargs, then this will do it:

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

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

like image 94
thebjorn Avatar answered Nov 15 '22 09:11

thebjorn


If you have only only 3 keyword args, Then this would be 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
like image 26
Bhargav Rao Avatar answered Nov 15 '22 08:11

Bhargav Rao