1
class Foo:
    def __init__(self, id: int, username: str):
        self.id = id
        self.username = username

dict = {'id':1,'username':'bar', 'extra':0}
x = Foo(**dict)  # Foo.__init__() got an unexpected keyword argument 'extra'

I'm working with some web services that sometimes have extra data in the response that I don't care about. The simplified example above illustrates the problem. Is there a way to use a dictionary to initialize an object, without manually entering each desired key as an argument?

3
  • If you need to pass variable parameters to any function you should be using keyword arguments Commented Apr 5, 2022 at 6:07
  • 2
    Does this answer your question? How does one ignore extra arguments passed to a data class? Commented Apr 5, 2022 at 6:08
  • Ah, of course I find it right after I post. Add kwargs with an underscore as the final parameter: def __init__(self, id: int, username: str, **_): Commented Apr 5, 2022 at 6:08

1 Answer 1

2

Rather than trying to somehow ignore extraneous arguments, why not take a more flexible approach by accepting all parameters regardless of the order in which they are presented to the class constructor.

Then declare properties (getters & setters) to subsequently access the values.

For example:

class Foo:
    def __init__(self, **kwargs):
        self.kwargs = kwargs
    @property
    def username(self):
        return self.kwargs.get('username')
    @username.setter
    def username(self, value):
        self.kwargs['username'] = value
    @property
    def ident(self):
        return self.kwargs.get('ident')
    @ident.setter
    def ident(self, value):
        self.kwargs['ident'] = value
    def __repr__(self):
        return ', '.join(f'{k}={v}' for k, v in self.kwargs.items())


f = Foo(ident=123)
print(f.ident)
print(f.username)
f.username = 'Lancelot'
print(f.username)
print(f)

Output:

123
None
Lancelot
ident=123, username=Lancelot

The only disadvantage to this that I can think of (there may be others) is that you would not be able to distinguish between values that were not passed to the constructor and those that had a value of None. You'd need to make your getters more elaborate to handle that

Sign up to request clarification or add additional context in comments.

1 Comment

Ah...interesting! That is a much better way for sure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.