假设函数参数在 Python 中从左到右进行评估是否安全?
参考说明它是以这种方式发生的,但也许有一些方法可以改变这个顺序,这可能会破坏我的代码。
我想要做的是为函数调用添加时间戳:
l = []
l.append(f(), time.time())
我知道我可以按顺序评估参数:
l = []
res = f()
t = time.time()
l.append(res, t)
但它看起来不那么优雅,所以如果我可以依赖它,我更喜欢第一种方式。
假设函数参数在 Python 中从左到右进行评估是否安全?
参考说明它是以这种方式发生的,但也许有一些方法可以改变这个顺序,这可能会破坏我的代码。
我想要做的是为函数调用添加时间戳:
l = []
l.append(f(), time.time())
我知道我可以按顺序评估参数:
l = []
res = f()
t = time.time()
l.append(res, t)
但它看起来不那么优雅,所以如果我可以依赖它,我更喜欢第一种方式。
引用参考文档:
Python 从左到右计算表达式。
所以是的,你可以指望这一点(有一个例外,见下文)。
一个调用((...)
主要之后的部分,例如函数名)只是另一个表达式 primary,调用的参数只是更多的表达式。
注意:此规则有一个例外。*expression
在调用中使用时(扩展可迭代以形成额外的位置参数),然后在任何关键字参数表达式之前评估此表达式:
>>> 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')
链接的文档指出:
这样做的结果是,尽管
*expression
语法可能出现在显式关键字参数之后,但它在关键字参数[.]之前被处理。
是的,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