21

I have started to learn python, and I would like to ask you about something which I considered a little magic in this language.

I would like to note that before learning python I worked with PHP and there I haven't noticed that.

What's going on - I have noticed that some call constructors or methods in Python are in this form.

object.call(variable1 = value1, variable2 = value2)

For example, in FLask:

app.run(debug=True, threaded=True)

Is any reason for this convention? Or is there some semantical reason outgoing from the language fundamentals? I haven't seen something like that in PHP as often as in Python and because I'm really surprised. I'm really curious if there is some magic or it's only convention to read code easier.

asked Aug 12, 2013 at 19:42
2
  • 3
    docs.python.org/2/tutorial/controlflow.html#keyword-arguments explains it all fairly well. Commented Aug 12, 2013 at 19:46
  • I had the exact opposite experience a few years ago, coming to PHP from Python and being confused when f($a=true) was accepted, but didn't do what I thought it did. Commented Aug 12, 2013 at 22:02

5 Answers 5

30

These are called keyword arguments, and they're usually used to make the call more readable.

They can also be used to pass the arguments in a different order from the declared parameters, or to skip over some default parameters but pass arguments to others, or because the function requires keyword arguments... but readability is the core reason for their existence.

Consider this:

app.run(True, False)

Do you have any idea what those two arguments mean? Even if you can guess that the only two reasonable arguments are threading and debugging flags, how can you guess which one comes first? The only way you can do it is to figure out what type app is, and check the app.run method's docstring or definition.

But here:

app.run(debug=True, threaded=False)

It's obvious what it means.


It's worth reading the FAQ What is the difference between arguments and parameters?, and the other tutorial sections near the one linked above. Then you can read the reference on Function definitions for full details on parameters and Calls for full details on arguments, and finally the inspect module documentation on kinds of parameters.

This blog post attempts to summarize everything in those references so you don't have to read your way through the whole mess. The examples at the end should also serve to show why mixing up arguments and parameters in general, keyword arguments and default parameters, argument unpacking and variable parameters, etc. will lead you astray.

answered Aug 12, 2013 at 19:47
Sign up to request clarification or add additional context in comments.

3 Comments

It's worth pointing out that a function can accept keyword arguments that aren't explicitly defined via the **kwargs argument.
@chepner: Well, maybe, but only if you also explain about keyword parameters, and about the *args parameter, and about passing variable arguments and keyword dicts, which makes things a lot more complicated. It's worth understanding the basics first, and then reading the rest of the tutorial...
@chepner: I've tried to add sufficient links that someone can actually find the information they need to get to the point where **kwargs makes sense, and then learn exactly how it works. But probably there's a better way to include that information. Any suggestions?
5

Specifying arguments by keyword often creates less risk of error than specifying arguments solely by position. Consider this function to compute loan payments:

def pmt(principal, interest, term):
 return **something**;

When one tries to compute the amortization of their house purchase, it might be invoked thus:

payment = pmt(100000, 4.2, 360)

But it is difficult to see which of those values should be associated with which parameter. Without checking the documentation, we might think it should have been:

payment = pmt(360, 4.2, 100000)

Using keyword parameters, the call becomes self-documenting:

payment = pmt(principal=100000, interest=4.2, term=360)

Additionally, keyword parameters allow you to change the order of the parameters at the call site, and everything still works correctly:

# Equivalent to previous example
payment = pmt(term=360, interest=4.2, principal=100000)

See http://docs.python.org/2/tutorial/controlflow.html#keyword-arguments for more information.

answered Aug 12, 2013 at 19:51

2 Comments

Misses out default values.
@SteveBarnes - Precisely. I wrote this response because others were focused on default values ... which the OP never asked about.
0

They are arguments passed by keywords. There is no semantical difference between keyword arguments and positional arguments.

They are often used like "options", and provide a much more readable syntax for this circumstance. Think of this:

>>> sorted([2,-1,3], key=lambda x: x**2, reverse=True)
[3, 2, -1]

Versus(python2):

>>> sorted([2,-1,3], None, lambda x: x**2, True)
[3, 2, -1]

In this second example can you tell what's the meaning of None or True?

Note that in keyword only arguments, i.e. arguments that you can only specify using this syntax, were introduced in python3. In python2 any argument can be specified by position(except when using **kwargs but that's another issue).

answered Aug 12, 2013 at 19:50

3 Comments

The last part of this is misleading. Keyword-only parameters were introduced in Python 3; there's no such thing as keyword-only arguments. But everything other than the final note is correct, and nicely explained.
@abarnert I use the words argument and parameter as synonyms. I don't see why they should be distinguished. I have always lived with this ambiguity and it doesn't give any particular problem. In fact, the last paragraph clearly refers to what you call parameters since otherwise the sentence "arguments that you can only specify using this syntax," does't have any meaning, hence there is no ambiguity.
Python explicitly distinguishes the two terms. The Python FAQ has an entry that explains why. More generally, every language has such a distinction... but some of them use different terminology (like "actual parameter" vs. "formal parameter"). The fact that you can sometimes get away with mixing them up doesn't mean you should; it means you should be extra careful not to, because that will lead you astray when you deal with cases where you can't get away with it—and will often lead your readers astray even when you can.
-1

There is no "magic".

A function can take:

  • Positional arguments (args)
  • Keyworded arguments (kwargs)

Always is this order.

Try this:

def foo(*args, **kwargs):
 print args
 print kwargs
foo(1,2,3,4,a=8,b=12)

Output:

(1, 2, 3, 4)
{'a': 8, 'b': 12}

Python stores the positional arguments in a tuple, which has to be immutable, and the keyworded ones in a dictionary.

answered Aug 12, 2013 at 19:49

3 Comments

Python only stores positional arguments whose index doesn't match a keyword-or-positional parameter (or a positional-only parameter, but you don't have those in functions defined in Python) in the var-positional sequence, and it only stores keyword arguments whose name doesn't match a keyword-or-positional or keyword-only parameter in the var-keyword mapping. Since the OP is asking about a function that has two keyword-or-positional parameters, this isn't relevant here. No such dict is constructed or passed anywhere.
I agree, but can't an answer try to show some additional things not already explained by other answers?
Sure, an answer can be useful even though it's a digression... but a misleading answer doesn't become useful just because it's a digression.
-2

The main utility of the convention is that it allows for setting certain inputs when there may be some defaults in between. It's particularly useful when a function has many parameters, most of which work fine with their defaults, but a few need to be set to other values for the function to work as desired.

example:

def foo(i1, i2=1, i3=3, i4=5):
 # does something
foo(1,2,3,4)
foo(1,2,i4=3)
foo(1,i2=3)
foo(0,i3=1,i2=3,i4=5)
answered Aug 12, 2013 at 19:47

12 Comments

Setting default values when defining the function is a somewhat separate issue from using keyword arguments when calling the function.
I don't think so. If you are bypassing an input via keywords, then the bypassed inputs need/should have default values, no?
@Jim: No. Read the FAQ What is the difference between arguments and parameters, and then look at how they're defined. You can pass keyword arguments for parameters that have no defaults. For example, def f(a, b): pass, then f(b=1, a=2) works just fine.
@Jim Defaults have nothing to do with being keyword arguments. For example def f(*, a): print(a) is a function with a keyword argument without a default value(python3). You can also see a side effect of this when you use unpacking of positional arguments mixed with keyword arguments in python2.
My point was that you can make use of default values without calling the function using keyword arguments, and you can use keyword arguments with a function that does not specify default parameter values.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.