这是您可以记住Python函数的方法:
def memo_square(a, cache={}): if a not in cache: cache[a] = a*a return cache[a]
接待是鲜为人知的,因此在削减范围内,我们将分析其工作原理和用途。
首先,它如何以及为什么起作用。
memo_square
(与其他任何函数一样)是函数类的对象,除其他属性外,还创建了创建对象时会填充的
memo_square.__defaults__
元组。 首先,它包含一个空字典,如函数头所示:
>>> memo_square.__defaults__ ({},)
__defaults__
是一个常规元组,您不能更改其元素。 是的,您可以一次替换整个默认值集,但只能替换为另一个元组:
>>> def test(a=1, b=2): ... print(a, b) ... >>> test.__defaults__ (1, 2) >>> test() 1 2 >>> test.__defaults__ = (', ', '') >>> test() , >>> test.__defaults__[1] = '' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> test.__defaults__ = {0: ', ', 1: ''} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __defaults__ must be set to a tuple object
Soryan,本文不会涉及Picaba。 好吧,这并不重要。 重要的是,除了非常狡猾的代码外,
func.__defaults__
在程序运行期间连同其所有元素一起创建了一次。 元组及其元素不会在每次函数调用时都被重新创建,只要存在该函数,就将使用它们。 但是要改变,如果元素本身是可变的,没有人会禁止它们。 无法使用此类元素是
用python射击自己的最常见方法之一 。 但是实际上在函数调用之间保存值可能非常有用。 几次调用后,
memo_square.__defaults__
将如下所示:
>>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4},) >>> memo_square(5) 25 >>> memo_square.__defaults__ ({2: 4, 5: 25},) >>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4, 5: 25},)
如果已经为相同的值调用了该函数,则将计算该值,并且因此不补充高速缓存。 对于一个正方形,好处很小(严格来说,对于一个正方形,好处是负面的,因为在字典中搜索比将两个数相乘更昂贵),但是对于真正昂贵的函数,记忆/缓存可能会有用。 当然,您可以通过多种方式在python中提供它。 以下是我们的替代方案:
这种记忆方法所失去的主要优点是它不是很惯用。 就个人而言,当我第一次偶然发现这个决定时,我花了几分钟思考一下这里发生了什么以及为什么。 另一方面,在这几分钟内,我开始更好地了解Python函数及其参数的排列方式。 因此,即使您不使用默认参数(例如用于记忆或
加快名称解析速度 ),了解此技术对于任何营养学家仍然有用。