7 ms·
Why do people not just type everything they want passed? def variable(n:str, nn:str, nnn:str, *, a:int, b:int, c:int) Anything after,*, is a kwarg.
by vorticalbox 3y ago
Why do people not just type everything they want passed?
def variable(n:str, nn:str, nnn:str, *, a:int, b:int, c:int)
Anything after,*, is a kwarg.
- masklinn 3y agoYour signature requires exactly 3 positional[0] and 3 keyword arguments. The OP allows any number of either. [0] actually 3 positional-or-keyword which is even more widely divergent
- vorticalbox 3y agoBut why would you want that doesn't that make for a more confusing api? Would it not be better to just have everything as a kwarg? You would get better types that way
- masklinn 3y agoI genuinely don’t understand what you are asking.
- zbentley 3y agoI think what GP is saying is that with explicit kwargs you can't express variadic signatures, i.e. "this function takes one int positional, and then any number of key/value pairs where the values are lists". The variable length is the important bit. It's certainly debatable whether doing that is better than passing a single argument whose value is a dict with that same type, but many people do prefer the variadic args/kwargs style.
- Znafon 3y agoIt is used when the number of argument can vary, like: def sum(*args: int) -> int: if len(args) == 0: return 0 return args[0] + sum(*args[1:])
- zoomablemind 3y agoIt seems altogether surprising that with an empty list or tuple a, a[1] results in index error, yet a[1:] quietly returns an empty list or tuple.
- hk__2 3y ago> It seems altogether surprising that with an empty list or tuple a, a[1] results in index error, yet a[1:] quietly returns an empty list or tuple. `a[1:]` returns the sequence of elements that start at index 1. If there is no such element, the list is empty. I don’t see any good reason why this should throw an error.
- macintux 3y agoThen why doesn’t a[1] return None? I understand the logic behind both decisions, but it’s not surprising that people find it inconsistent and unintuitive.
- hk__2 3y ago> Then why doesn’t a[1] return None? Because there would be no way to distinguish between "a[1] contains None" and "a[1]" doesn’t exist.
- macintux 3y agoAnd with a[1:] returning the empty list there’s no way to distinguish between a is empty and a only has one element. These are, in the end, relatively arbitrary language design decisions.
- akasakahakada 3y agoWhen you slice a list, you get a list. When you see there is nothing inside the returning list, you know that means end of list, contains zero element. Slicing and indexing return object at different level.
- deleted 3y ago[deleted]
- Frotag 3y agoIt's pretty common when wrapping a function that has a large number of config options. The wrapper is usually some shorthand for building a handful of those args or adding some side-effect, while still allowing the caller access to the remaining config options via kwargs. Here's one example of that in the wild https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html#matplotlib.pyplot.savefig https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot....
- dragonwriter 3y ago> Anything after,*, is a kwarg. A required positional OR kwarg as you’ve done it. Its closer to an optional kwarg if you expand the type declaration to also allow None and set a None default. But there are times when you want to leave the number and names of kwargs open (one example is for a dynamic wrapper—a function that wraps another function that can be different across invocations.)
- jpc0 3y agoIf you have enough arguments that the signature becomes obscure to read you need a dataclass to pass into the function instead. I would rather: @dataclass(frozen=True, slots=True) class VarThings: n: int ... def variable(a: VarThings): ... Than a million args
- b5n 3y agoI usually start with a namedtuple unless I need the additional features provided by a dataclass.
- joshuamorton 3y agoWhy? Dataclasses are vastly better: more typesafe, less hacky, etc.
- akvadrako 3y agoThe new syntax is basically the same as dataclasses: class Employee(NamedTuple): name: str id: int
- IshKebab 3y agoIn my experience it's generally because Python developers make functions with an insane number of keyword arguments, and then wrap those functions. They don't want to type them all out again so they use kwargs. subprocess.run() is an example of that. Also check out the functions in manim. The inability to properly static type kwargs using TypedDict is probably the biggest flaw in Python's type hint system (after the fact that hardly anyone uses it of course).