Jon*_*han 59 python arguments mutable default-value
在Python中将一个可变对象设置为函数中参数的默认值是一个常见的错误.以下是David Goodger撰写的优秀文章中的一个例子:
>>> def bad_append(new_item, a_list=[]):
a_list.append(new_item)
return a_list
>>> print bad_append('one')
['one']
>>> print bad_append('two')
['one', 'two']
Run Code Online (Sandbox Code Playgroud)
之所以出现这种情况的解释是在这里.
现在我的问题是:这个语法有一个很好的用例吗?
我的意思是,如果遇到它的每个人都犯了同样的错误,调试它,理解问题,从而试图避免它,这种语法有什么用?
Dun*_*can 42
您可以使用它在函数调用之间缓存值:
def get_from_cache(name, cache={}):
if name in cache: return cache[name]
cache[name] = result = expensive_calculation()
return result
Run Code Online (Sandbox Code Playgroud)
但通常使用类可以做得更好,因为您可以使用其他属性来清除缓存等.
Pet*_*ica 14
规范的答案是这个页面:http : //effbot.org/zone/default-values.htm
它还提到了可变默认参数的 3 个“好”用例:
我知道这是一个旧的,但只是为了它我想添加一个用例到这个线程。我定期为 TensorFlow/Keras 编写自定义函数和层,将脚本上传到服务器,在那里训练模型(使用自定义对象),然后保存模型并下载它们。为了加载这些模型,我需要提供一个包含所有这些自定义对象的字典。
在像我这样的情况下,您可以做的就是向包含这些自定义对象的模块添加一些代码:
custom_objects = {}
def custom_object(obj, storage=custom_objects):
storage[obj.__name__] = obj
return obj
Run Code Online (Sandbox Code Playgroud)
然后,我可以装饰字典中需要的任何类/函数
@custom_object
def some_function(x):
return 3*x*x + 2*x - 2
Run Code Online (Sandbox Code Playgroud)
此外,假设我想将自定义损失函数存储在与自定义 Keras 层不同的字典中。使用 functools.partial 让我可以轻松访问新的装饰器
import functools
import tf
custom_losses = {}
custom_loss = functools.partial(custom_object, storage=custom_losses)
@custom_loss
def my_loss(y, y_pred):
return tf.reduce_mean(tf.square(y - y_pred))
Run Code Online (Sandbox Code Playgroud)
import random
def ten_random_numbers(rng=random):
return [rng.random() for i in xrange(10)]
Run Code Online (Sandbox Code Playgroud)
使用random
模块,实际上是一个可变单例,作为其默认随机数生成器.
也许您不改变可变参数,但是期望可变参数:
def foo(x, y, config={}):
my_config = {'debug': True, 'verbose': False}
my_config.update(config)
return bar(x, my_config) + baz(y, my_config)
Run Code Online (Sandbox Code Playgroud)
(是的,我知道您可以config=()
在这种特殊情况下使用,但是我发现这不太清楚,也不太笼统。)
归档时间: |
|
查看次数: |
7022 次 |
最近记录: |