Pattern to work around the static value of a python default argument

huangapple go评论58阅读模式
英文:

Pattern to work around the static value of a python default argument

问题

Python有这个令人惊讶的特性,即默认参数只会在函数/方法定义时评估一次:

from datetime import datetime
import time

def some_func(ts: datetime = datetime.now()):
    print("现在是什么时间?", ts)

some_func()
time.sleep(5)   # 睡眠5秒
some_func()

输出:

现在是什么时间 2023-08-08 18:43:43.697853
现在是什么时间 2023-08-08 18:43:43.697853

是的,这种行为是有文档记录的。这也超出了我以前的经验,因为我自80年代以来在数十种编程语言中工作过。更近期的语言,如Scala(以及之前的Java),显然不采用这种方式。是否有一种模式可以实现在调用时评估默认值以获得相同的结果呢?

英文:

Python has this stunning characteristic that default parameters are evaluated once - at the time the function/method is defined:

from datetime import datetime
import time
def some_func(ts: datetime = datetime.now()):
    print("What time is it 'now'?",ts)

some_func()
time.sleep(5)   # sleeps 5 seconds
some_func()

Prints:

What time is it 'now'? 2023-08-08 18:43:43.697853
What time is it 'now'? 2023-08-08 18:43:43.697853

Yes this behavior is documented. It is also beyond my prior experience having worked in dozens of languages since the early eighties. More recent languages such as scala (and java before that) certainly do not take that angle on it. Is there any pattern to use that can achieve the same result as evaluating default values at invocation time ?

答案1

得分: 3

这个问题也会出现在可变默认参数的情况下。解决方法相同:使用默认参数的标志值(例如None),然后在函数体中进行检查:

def some_func(ts: datetime=None):
    if ts is None:
        ts = datetime.now()
    print("现在是什么时间?", ts)
英文:

This problem also arises with mutable default arguments. The solution is the same: Use a sentinel value for the default argument (e.g. None), then check for it in the function body:

def some_func(ts: datetime=None):
    if ts is None:
        ts = datetime.now()
    print("What time is it 'now'?",ts)

答案2

得分: 2

将默认值设置为None。

然后添加一个保护性条件,如果参数为None,则将该值设置为您的动态默认值。

当您希望默认参数为空列表、字典或其他集合时,这点特别重要。

from datetime import datetime
import time
def some_func(ts: datetime = None):
    if ts is None:
        ts=datetime.now()
    print("现在是什么时间?",ts)

some_func()
time.sleep(5)   # 等待5秒
some_func()

输出

现在是什么时间? 2023-08-08 21:07:07.692347
现在是什么时间? 2023-08-08 21:07:12.697683
英文:

Set the default to None.

Then add a guard clause to set the value to your dynamic default value if the parameter is None.

This is especially important when you want the default parameter to be an empty list, dict, or other collection.

from datetime import datetime
import time
def some_func(ts: datetime = None):
    if ts is None:
        ts=datetime.now()
    print("What time is it 'now'?",ts)

some_func()
time.sleep(5)   # sleeps 5 seconds
some_func()

Output

What time is it 'now'? 2023-08-08 21:07:07.692347
What time is it 'now'? 2023-08-08 21:07:12.697683

huangapple
  • 本文由 发表于 2023年8月9日 09:48:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76864083-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定