You'll have to move your keyword arguments to a variable keyword capture too:
def foo(*args, **kw):
a = kw.get('a', MyComplexObject())
b = kw.get('b', b=Something())
print a, b, args
Python will fill the two keyword arguments first otherwise, as in Python 2 there is no way to specify that these keywords cannot be filled by positional arguments.
Python 3 changed the interpretation of the positional catchall parameter to make this possible without forcing you to use the ** keyword parameter catch-all.
If you cannot change the function definition yourself or upgrade to Python 3, then your only recourse is to specify the defaults again, or retrieve them from the function (using the inspect.getargspec() convenience function):
import inspect
defaults = inspect.getargspec(foo).defaults
foo(*(defaults + (1,2,3)))
defaults here is a tuple of the keyword argument default values.
Demonstration:
>>> import inspect
>>> def foo(a='spam', b='foo', *args):
... print a, b, args
...
>>> defaults = inspect.getargspec(foo).defaults
>>> foo(*(defaults + (1,2,3)))
spam foo (1, 2, 3)
a&bare only instantiated once,so it's the same asdefault_a = MyComplexObject(),def foo(a=default_a):; args come before kwargs in python 2.7 too.