英文:
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
是的,这种行为是有文档记录的。这也超出了我之前在八十年代以来使用过的几十种语言的经验范围。更近期的语言,如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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论