Python 为什么默认值在对象之间共享
Python中的默认值概念基于使用可变或不可变对象。好的编程实践是不要使用可变对象作为默认值。相反,使用None作为默认值以避免出现问题。不可变对象(如数字、字符串、元组和None)不会发生变化。对于可变对象(如字典、列表和类实例)的更改可能导致混淆。
让我们看一个函数中字典的示例以及其中的问题以及如何解决它。
问题
我们有一个函数。其中有一个字典作为参数并具有默认值。第一次调用此函数时,mydict包含一个项目。第二次调用时,mydict包含两个项目,因为当foo()开始执行时,mydict已经包含一个项目。
def foo(mydict={}):
... calculate...
mydict[key] = value
return mydict
我们经常期望函数调用使用默认值时会创建新的对象。然而,并不是这样的。默认值只会在函数定义时创建一次。如果该对象被修改,比如上面的字典示例, 后续对该函数的调用将引用这个已经改变的对象。
解决方案
要解决使用可变对象作为默认值的问题,可以这样进行修复 –
def foo(mydict={}):
...
使用像None这样的不可变对象 –
def foo(mydict=None):
if mydict is None:
mydict = {}
当你有一个计算耗时的函数时,一种技术是缓存每次对函数的调用的参数和结果值,并且如果再次请求同样的值,返回缓存的结果值。
这称为memoizing,可以这样实现 –
# Callers can only provide two parameters and optionally pass _cache by keyword
def expensive(arg1, arg2, *, _cache={}):
if (arg1, arg2) in _cache:
return _cache[(arg1, arg2)]
# Calculate
result = ... expensive computation ...
_cache[(arg1, arg2)] = result
return result
以下内容将结果存储在缓存中 −
_cache[(arg1, arg2)] = result