<p>Python提供了一种非常优雅的方法来完成这个任务-decorators。基本上,decorator是在不更改函数源代码的情况下包装另一个函数以提供附加功能的函数。你的装潢师可以这样写:</p>
<pre><code>import json
def persist_to_file(file_name):
def decorator(original_func):
try:
cache = json.load(open(file_name, 'r'))
except (IOError, ValueError):
cache = {}
def new_func(param):
if param not in cache:
cache[param] = original_func(param)
json.dump(cache, open(file_name, 'w'))
return cache[param]
return new_func
return decorator
</code></pre>
<p>一旦你得到了它,就可以用@语法“修饰”函数了。</p>
<pre><code>@persist_to_file('cache.dat')
def html_of_url(url):
your function code...
</code></pre>
<p>请注意,这个decorator是故意简化的,可能不适用于每种情况,例如,当源函数接受或返回无法进行json序列化的数据时。</p>
<p>关于decorators的更多信息:<a href="https://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python/1594484#1594484">How to make a chain of function decorators?</a></p>
<p>下面是如何使decorator在退出时仅保存一次缓存:</p>
<pre><code>import json, atexit
def persist_to_file(file_name):
try:
cache = json.load(open(file_name, 'r'))
except (IOError, ValueError):
cache = {}
atexit.register(lambda: json.dump(cache, open(file_name, 'w')))
def decorator(func):
def new_func(param):
if param not in cache:
cache[param] = func(param)
return cache[param]
return new_func
return decorator
</code></pre>