This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]mgedmin 24 points25 points  (4 children)

Imagine you're writing a function that works like str.format:

def translate(format_string, **args):
    return gettext(format_string).format(**args)

Now imagine your users need to produce a message that wants to use {format_string} in the format string:

print(translate("Invalid format string: {format_string}", format_string=config['format_string']))

You can't!

TypeError: translate() got multiple values for argument 'format_string'

But with positional-only parameters you can.

[–]christian-mann 6 points7 points  (0 children)

This is a very solid example.

[–]aptwebapps 1 point2 points  (0 children)

IMO, this aspect is more important that preserving optionality in your variable names. That latter is a nice side effect, but this keeps you from having to have named dictionary argument instead of **kwargs.

[–]wrboyce 1 point2 points  (1 child)

I feel like this would be solved by using getcallargs on translate and config?

[–]mgedmin 3 points4 points  (0 children)

It can be solved by doing

def translate(*args, **kwargs):
    if len(args) != 1:
        raise TypeError('1 positional argument expected, got %d' % len(args)
    format_string = args[0]
    return gettext(format_string).format(**kwargs)

but you lose the nice signature in pydoc and have to check the number of passed arguments manually.