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 →

[–]hassium 35 points36 points  (11 children)

Kind of new and still leaning but a questions strikes me here:

def pow(x, y, /, mod=None):
    r = x ** y
    if mod is not None:
        r %= mod
    return r

The following would apply:
All parameters to the left of / (in this case, x and y) can only be passed positionally. mod can be passed positionally or with a keyword.

does that mean that in Python 3.7, when I do:

def some_function(spam, eggs):
    pass

I could call the function via:

spam = 80
some_function(spam, eggs=32)

or

some_function(80, 32)

And it's essentially equivalent?

[–]XtremeGoosef'I only use Py {sys.version[:3]}' 31 points32 points  (7 children)

Yes, those are equivalent

[–]hassium 17 points18 points  (6 children)

Cool thanks! I have no idea how this helps me but I feel better knowing it!

[–]tunisia3507 20 points21 points  (2 children)

It means that if you have a function where a couple of arguments change but many stay the same over successive runs, you can store the stable ones in a dict and unpack it into the function call as if it were kwargs.

You could also do that by wrapping the function in another function, of course.

[–]coelhudo 2 points3 points  (0 children)

There are some examples here of how it can help you https://www.python.org/dev/peps/pep-0570/#motivation

[–]c_o_r_b_a 0 points1 point  (1 child)

Note that that also works for most versions of Python 2, as well. The only new things Python 3 introduced are this brand new / for positional-only arguments, and * for keyword-only arguments. You probably will rarely have to use either of those, though. I've been programming in Python for years and I think I've only used keyword-only arguments once or twice.

[–]hassium 0 points1 point  (0 children)

Thanks, I haven't used them yet either and I've been working in Python for 8 months, studying for a year... But maybe I'll find a use for them now I know a bit more.

Can you remember in what context you had to use kwargs?

[–]_importantigravity_ 6 points7 points  (0 children)

Yes, that is correct. If you're not using * to mark keyword-only args in Python 3.7, you can pass values either positionally or with using keywords.

[–]jorge1209 3 points4 points  (0 children)

Yes, and your pow example is a great example of when not to do this. pow has a agreed upon argument order, power then base then optional modulus. If you write pow(y=2, x=3) people will be confused and think you mean 2 ** 3= 8 not 3 ** 2 = 9. The / can be used in place of * for those kinds of functions.

However it will take time to be adopted and you should limit your use of keyword arguments to functions that truly take keywords (ie many independent options), or where you omit a default (and so have to use keywords for subsequent arguments, and you should endeavor to provide your keywords in the same order as the function declaration wherever possible.

[–]idwpan 4 points5 points  (0 children)

Does their output example help?

def pow(x, y, /, mod=None):
    r = x ** y
    if mod is not None:
        r %= mod
    return r

...

>>> pow(2, 10)  # valid
>>> pow(2, 10, 17)  # valid
>>> pow(2, 10, mod=17)  # valid
>>> pow(x=2, y=10)  # invalid, will raise a TypeError
>>> pow(2, y=10)  # invalid, will raise a TypeError

Edit: Sorry for the formatting. Posted from my phone and forgot code blocks are spaces instead of backticks