依赖Python函数参数评估顺序是否安全?

Pho*_*nix 27 python arguments operator-precedence

假设在Python中从左到右计算函数参数是否安全?

参考说明它发生的方式,但也许有一些方法来改变这个可能会破坏我的代码的顺序.

我想要做的是为函数调用添加时间戳:

l = []
l.append(f(), time.time())
Run Code Online (Sandbox Code Playgroud)

我知道我可以按顺序评估参数:

l = []
res = f()
t = time.time()
l.append(res, t)
Run Code Online (Sandbox Code Playgroud)

但它看起来不那么优雅,所以如果我可以依赖它,我更喜欢第一种方式.

Mar*_*ers 36

引用参考文档:

Python从左到右评估表达式.

所以是的,你可以依靠它(有一个例外,见下文).

呼叫(在(...)伯,诸如功能名称之后的部分)是另一种表达初级,以及该呼叫的参数只是多个表达式.

注意:此规则有一个例外.*expression在调用中使用(扩展iterable以形成其他位置参数)时,将在任何关键字参数表达式之前计算此表达式:

>>> 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')
Run Code Online (Sandbox Code Playgroud)

链接的文档说明:

这样做的结果是虽然*expression语法可能出现在显式关键字参数之后,但它在关键字参数[.]之前被处理.

  • 这是一个比另一个更好的答案,指出它可以在语言参考中找到.另一个只是表明它是这种方式,但它并不能证明它应该总是这样. (10认同)

orl*_*rlp 13

是的,Python总是从左到右评估函数参数.

据我所知,这适用于任何逗号分隔列表:

>>> from __future__ import print_function
>>> def f(x, y): pass
...
>>> f(print(1), print(2))
1
2
>>> [print(1), print(2)]
1
2
[None, None]
>>> {1:print(1), 2:print(2)}
1
2
{1: None, 2: None}
>>> def f(x=print(1), y=print(2)): pass
...
1
2
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,例子不能证明这不是*未定义的行为*. (6认同)