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