[Python高效编程] - 实现用户历史记录功能

开发环境

  1. Python版本: python3.6
  2. 调试工具:pycharm 2017.1.3
  3. 电脑系统:Windows 10 64位系统
  4. Python需求库:random,collections, pickle

举例说明

制作一个猜数字的小游戏

from random import randint

N = randint(0, 100)

def guess(k):
    if k == N:
        print("right")
        return True
    elif k < N:
        print("{0} is less-than N".format(k))
    else:
        print("{0} is greater-than N".format(k))
    return False

while True:
    line = input("please input a number: ")
    if line.isdigit():
        # 判断是否为数字
        k = int(line)
        if guess(k):
            break


please input a number: 1
1 is less-than N
please input a number: 2
2 is less-than N
please input a number: 30
30 is less-than N
please input a number: 60
60 is less-than N
please input a number: 90
90 is greater-than N
please input a number: 80
80 is less-than N
please input a number: 88
88 is greater-than N
please input a number: 85
85 is less-than N
please input a number: 86
86 is less-than N
please input a number: 87
right

有时候用户需要输入很多次,想要查看一下历史记录,那么怎么解决呢?

解决方案

这时候可以使用标准库 collections中的deque,这是一个双端循环队列

deque 使用说明

In [1]: from collections import deque

In [2]: q = deque([], 5)

In [3]: q.append(1)

In [4]: q
Out[4]: deque([1])

In [5]: q.append(2)

In [6]: q.append(3)

In [7]: q.append(4)

In [8]: q
Out[8]: deque([1, 2, 3, 4])

In [9]: q.append(5)

In [10]: q
Out[10]: deque([1, 2, 3, 4, 5])

In [11]: q.append(6)

In [12]: q
Out[12]: deque([2, 3, 4, 5, 6])

In [13]: q.append(7)

In [14]: q
Out[14]: deque([3, 4, 5, 6, 7])

这里创建了一个只能存5个元素的双端队列,当存了6个值的时候,舍弃第一个值,保存第六个值

猜数字游戏改进

from random import randint
from collections import deque

N = randint(0, 100)
history = deque([], 5)

def guess(k):
    if k == N:
        print("right")
        return True
    elif k < N:
        print("{0} is less-than N".format(k))
    else:
        print("{0} is greater-than N".format(k))
    return False

while True:
    line = input("please input a number: ")
    if line.isdigit():
        # 判断是否为数字
        k = int(line)
        history.append(k)
        # 添加历史记录
        if guess(k):
            break
    elif line == 'history' or line == "?":
        print(list(history))


please input a number: 1
1 is less-than N
please input a number: 100
100 is greater-than N
please input a number: 50
50 is greater-than N
please input a number: ?
[1, 100, 50]
please input a number: 40
40 is greater-than N
please input a number: 30
30 is greater-than N
please input a number: ?
[1, 100, 50, 40, 30]
please input a number: 20
20 is greater-than N
please input a number: 10
10 is less-than N
please input a number: ?
[50, 40, 30, 20, 10]
please input a number: 15
15 is greater-than N
please input a number: 13
13 is greater-than N
please input a number: ?
[30, 20, 10, 15, 13]
please input a number: 11
11 is less-than N
please input a number: 12
right

这个队列只是存储在内存中,再次调用的时候无法读取上次的值,所有应该使用文件保存记录

将记录保存进文件

pickle包基本使用

Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pickle

In [2]: from collections import deque

In [3]: q = deque([1, 2, 3, 4, 5], 5)

In [4]: pickle.dump?
Signature: pickle.dump(obj, file, protocol=None, *, fix_imports=True)
Docstring:
Write a pickled representation of obj to the open file object file.

This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may
be more efficient.

The optional *protocol* argument tells the pickler to use the given
protocol supported protocols are 0, 1, 2, 3 and 4.  The default
protocol is 3; a backward-incompatible protocol designed for Python 3.

Specifying a negative protocol version selects the highest protocol
version supported.  The higher the protocol used, the more recent the
version of Python needed to read the pickle produced.

The *file* argument must have a write() method that accepts a single
bytes argument.  It can thus be a file object opened for binary
writing, an io.BytesIO instance, or any other custom object that meets
this interface.

If *fix_imports* is True and protocol is less than 3, pickle will try
to map the new Python 3 names to the old module names used in Python
2, so that the pickle data stream is readable with Python 2.
Type:      builtin_function_or_method

In [5]:  pickle.dump(q, open("history", 'wb'))

In [6]: q2 = pickle.load(open("history", "rb"))

In [7]: q2
Out[7]: deque([1, 2, 3, 4, 5])

改进最终代码

from random import randint
from collections import deque
import pickle

N = randint(0, 100)
history = deque([], 5)

def guess(k):
    if k == N:
        print("right")
        return True
    elif k < N:
        print("{0} is less-than N".format(k))
    else:
        print("{0} is greater-than N".format(k))
    return False

while True:
    line = input("please input a number: ")
    if line.isdigit():
        # 判断是否为数字
        k = int(line)
        history.append(k)
        pickle.dump(history, open("history.txt", 'wb'))
        # 添加历史记录
        if guess(k):
            break
    elif line == 'history' or line == "?":
        try:
            q2 =  pickle.load(open("history.txt", "rb"))
        except:
            pass
        print(list(q2))


你可能感兴趣的:(Python)