Does something like the following class exist in the Python stdlib (or maybe in some other very common lib)?
class Args:
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
Background
(Although this is just one example, I can imagine that there are more potential use cases.)
I frequently have the pattern that some function forwards the kwargs
to another, or even some of the args
.
Examples:
class Super: ...
class Foo(Super):
def __init__(self, foo, **kwargs):
super().__init__(**kwargs)
def basic_func(x, opt1, opt2): ...
def higher_level_func(opt3, opt4, **kwargs):
...
y = basic_func(x, **kwargs)
...
Sometimes when it gets more complex, you see patterns like this:
def basic_foo(x, foo1, foo2): ...
def basic_bar(x, bar1, bar2): ...
def higher_level_func(baz1, baz2, foo_opts: Dict[str,Any], bar_opts: Dict[str,Any]):
...
x = basic_foo(x, **foo_opts)
...
x = basic_bar(x, **bar_opts)
...
I want to generalize foo_opts: Dict[str,Any]
and bar_opts: Dict[str,Any]
in this last example to also allow for args
and not just `kwargs.
You could simply do this:
def higher_level_func(baz1, baz2, foo_args: Tuple[Any], foo_kwargs: Dict[str,Any], bar_args: Tuple[Any], bar_kwargs: Dict[str,Any]):
...
x = basic_foo(x, *foo_args, **foo_kwargs)
...
x = basic_bar(x, *bar_args, **bar_kwargs)
...
But that looks ugly. So I would want to do this instead:
def higher_level_func(baz1, baz2, foo_args: Args, bar_args: Args):
...
x = basic_foo(x, *foo_args.args, **foo_args.kwargs)
...
x = basic_bar(x, *bar_args.args, **bar_args.kwargs)
...
This looks like it would be a useful common pattern, so I wonder whether something like this already exists (maybe even in the stdlib).
Note that functools.partial
is also already close to what I want. It binds also the function itself (basic_foo
or basic_bar
in the example) which is fine. However, the order of the args is different:
foo = partial(basic_foo, *args, **kwargs)
...
foo(x) == basic_foo(*args, x, **kwargs)
And this is a problem, because I need the x
arg to be first here, and I would want that the partial
only binds the following args.
(Related, related, related.)
Bonus question
Somehow tell type checkers like MyPy or PyCharm to what function Args
matches, e.g. like Args[basic_foo]
. Not sure if this is feasible...