Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to rely on Python function arguments evaluation order? [duplicate]

Is it safe to assume that function arguments are evaluated from left to right in Python?

Reference states that it happens that way but perhaps there is some way to change this order which may break my code.

What I want to do is to add time stamp for function call:

l = [] l.append(f(), time.time()) 

I understand that I can evaluate the arguments sequentially:

l = [] res = f() t = time.time() l.append(res, t) 

But it looks less elegant so I'd prefer the first way if I can rely on it.

like image 811
Phoenix Avatar asked Jul 30 '13 13:07

Phoenix


People also ask

Does the order of arguments matter in Python?

Notice that when keyword arguments are used in the call, the order in which arguments are listed doesn't matter; Python matches by name, not position.

Does Python evaluate and statements in order?

Order of Evaluation In Python, the left operand is always evaluated before the right operand. That also applies to function arguments. Python uses short circuiting when evaluating expressions involving the and or or operators.

Can a Python function take multiple arguments?

Passing multiple arguments to a function in Python:We can pass multiple arguments to a python function by predetermining the formal parameters in the function definition.

Can Python take an unlimited number of arguments?

Unlimited Number of Positional Argument ValuesPython lets us define a function that handles an unknown and unlimited number of argument values. Examples of built-in functions with a unlimited number of argument values are max and min .


1 Answers

Quoting from the reference documentation:

Python evaluates expressions from left to right.

So yes, you can count on that (with one exception, see below).

A call (the (...) part after a primary, such as a function name) is just another expression primary, and the arguments for the call are just more expressions.

Note: There is one exception to this rule. When using *expression in a call (to expand an iterable to form additional positional arguments), then this expression is evaluated before any keyword argument expressions:

>>> from itertools import count >>> def bar(n, r=(), c=count()): print(f'{next(c)}: bar({n!r})'); return r ... >>> def foo(*args, **kwargs): pass ... >>> foo(bar('a1'), spam=bar('a2'), *bar('varargs'), **bar('kwargs', {})) 0: bar('a1') 1: bar('varargs') 2: bar('a2') 3: bar('kwargs') 

The linked documentation states:

A consequence of this is that although the *expression syntax may appear after explicit keyword arguments, it is processed before the keyword arguments[.]

like image 86
Martijn Pieters Avatar answered Sep 24 '22 05:09

Martijn Pieters