top | item 37282749

(no title)

Znafon | 2 years ago

It 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:])

discuss

order

ddejohn|2 years ago

That is an entirely different use-case than a function signature allowing arbitrary keyword arguments. Arbitrary keyword args are different than arbitrary positional args like you have in your example.

GP is suggesting that one should only ever use explicit keyword-only args (anything listed after `*,` in the signature) versus arbitrary keyword args implicit via `**kwargs`.

e.g. (omitting type hints for clarity):

    def sum(*args, **arbitrary_kwargs):
        ...
vs

    def sum(*args, some_keyword_only_arg):
        ...
In my opinion if one finds themselves writing code that uses arbitrary kwargs, they've got a design problem.**

zoomablemind|2 years 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.

hk__2|2 years 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.

js2|2 years ago

a[1] has to raise an IndexError because there's no return value it could use to otherwise communicate the item doesn't exist. Any such value could itself be a member of the sequence. To behave otherwise, Python would have to define a sentinel value that isn't allowed to be a member of a sequence.

When using slice notation, the return value is a sequence, so returning a zero-length sequence is sufficient to communicate you asked for more items than exist.

It may be surprising, but it almost always leads to more ergonomic code.

https://discuss.python.org/t/why-isnt-slicing-out-of-range/

esafak|2 years ago

You should use `Iterable`

Znafon|2 years ago

I'm not sure

    print(firstname, lastname)
for example is more readable than

    print((firstname, lastname))
especially since I would then have to write

    print((surname,))
to just print a single string.

Variadic functions are rather classic, I think Go, Rust, C and JavaScript also have them.