<p>只需使用<a href="https://docs.python.org/3/library/pickle.html#pickle-python-object-serialization" rel="nofollow">^{<cd1>}</a>或<a href="https://docs.python.org/2/library/json.html#module-json" rel="nofollow">^{<cd2>}</a>对数据进行<a href="http://en.wikipedia.org/wiki/Serialization" rel="nofollow">serialize</a>。下面是一个使用<code>json</code>序列化分数的示例(将分数存储在<a href="https://docs.python.org/3/library/stdtypes.html#mapping-types-dict" rel="nofollow">^{<cd4>}</a>-名称和分数之间的映射):</p>
<pre><code># import the serializing library
import json as serializer
</code></pre>
<p>现在我们将创建一个函数,将分数写入给定文件:</p>
^{pr2}$
<p>它的作用是:</p>
<ol>
<li>从score文件加载序列化结果对象(<code>dict</code>)</li>
<li>更新分数<code>dict</code>(add key/update value of key)</li>
<li>{{cd4}(更新了^}文件)</li>
</ol>
<p>在编写<code>write_score</code>函数时,我们缺少了一个<code>read_scores</code>函数,它使我们能够看到当前的分数。我们写下这个<code>read_scores</code>:</p>
<pre><code>def read_scores(score_file_name):
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
</code></pre>
<p><code>read_scores</code>的作用是:</p>
<ol>
<li>读取序列化的<code>dict</code>(使用<a href="https://docs.python.org/2/library/json.html#json.load" rel="nofollow">^{<cd14>}</a>)</li>
</ol>
<p>现在我们可以测试它是否真的有效。下面是一个小例子:</p>
<pre><code># set the score file name
SCORES_FILE_NAME = 'scores.txt'
write_score(SCORES_FILE_NAME, 'john', 10)
print(read_scores(SCORES_FILE_NAME))
write_score(SCORES_FILE_NAME, 'jim', 11)
print(read_scores(SCORES_FILE_NAME))
# overwrite john's score
write_score(SCORES_FILE_NAME, 'john', 12)
print(read_scores(SCORES_FILE_NAME))
</code></pre>
<p><strong>技巧1:</strong>在写分数时,您可能需要使用<a href="https://docs.python.org/2/library/stdtypes.html#str.lower" rel="nofollow">^{<cd15>}</a>,这样<code>john</code>和{<cd17>}被视为同一个用户。在</p>
<p><strong>技巧2:</strong>因为我们将<code>json</code>库作为<code>serializer</code>引用,并且它与<code>pickle</code>具有相同的API,您可以通过将<code>import json as serializer</code>替换为<code>import pickle as serializer</code>在这两者之间进行选择。<strong>只需确保删除分数文件,因为它们不会以相同的方式序列化数据</strong>。在</p>
<p><strong>将整个代码放在一起:</strong></p>
<pre><code># import the serializing library
import json as serializer
def write_score(score_file_name, name, score):
scores = read_scores(score_file_name)
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
def read_scores(score_file_name):
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
# TESTS
# set the score file name
SCORES_FILE_NAME = 'scores.txt'
write_score(SCORES_FILE_NAME, 'john', 10)
print(read_scores(SCORES_FILE_NAME))
write_score(SCORES_FILE_NAME, 'jim', 11)
print(read_scores(SCORES_FILE_NAME))
# overwrite john's score
write_score(SCORES_FILE_NAME, 'john', 12)
print(read_scores(SCORES_FILE_NAME))
</code></pre>
<p>输出:</p>
<pre><code>{u'john': 10}
{u'john': 10, u'jim': 11}
{u'jim': 11, u'john': 12}
</code></pre>
<p>要读取特定分数,可以使用现有方法<code>read_scores</code>:</p>
<pre><code>def read_score(score_file_name, name):
return read_scores(score_file_name)[name]
</code></pre>
<h2><strong>奖金-<a href="http://en.wikipedia.org/wiki/Closure_%28computer_programming%29" rel="nofollow">Closures</a>:</strong></h2>
<p>如果您了解闭包,可以使用以下方法使函数特定于文件:</p>
<pre><code>def write_score(score_file_name):
# create closure specific to 'score_file_name'
def write_score_specific(name, score):
scores = read_scores(score_file_name)
# we're going to make a 'read_scores' with closures as well!
# so use that one...
scores_reader = read_scores(score_file_name)
scores = scores_reader()
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
# return file-specific function
return write_score_specific
</code></pre>
<p>现在,我们只需调用带有file name参数<strong>的函数一次</strong>,从那时起,我们就可以使用结果来写分数:</p>
<pre><code># create specific 'write_score' for our file
score_txt_writer = write_score('scores.txt')
# update john's score to 10 without specifying the file
score_txt_writer('john', 10)
</code></pre>
<p>对<code>read_score</code>也做了同样的处理:</p>
<pre><code>def read_scores(score_file_name):
# create closure function
def read_scores_specific():
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
return read_scores_specific
</code></pre>
<p><strong>包含闭包的整个代码:</strong></p>
<pre><code># import the library
import serializer
# CLOSURES
SCORES_FILE = 'scores.txt'
def read_scores(score_file_name):
# create closure function
def read_scores_specific():
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
return read_scores_specific
def write_score(score_file_name):
# create closure specific to 'score_file_name'
def write_score_specific(name, score):
scores_reader = read_scores(score_file_name)
scores = scores_reader()
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
# return file-specific function
return write_score_specific
# create specific 'write_score' for our file
score_txt_writer = write_score(SCORES_FILE)
# update john's score to 10 without specifying the file
score_txt_writer('john', 10)
score_txt_reader = read_scores(SCORES_FILE)
print score_txt_reader()
</code></pre>
<p>输出:</p>
<pre><code>{u'john': 10}
</code></pre>