2019-08-10-1901100244-自学训练营-Python入门-Day03-学习心得

学员信息

  • 学号:1901100244
  • 操作系统:Windows 10 version 1903 (64-bit)
  • 学习内容:使用 Python 编写计算器
  • 学习用时:5 小时

收获总结

  1. 对 Python 可实现的功能大致有了些了解;
  2. 了解了获取键盘输入信息的方法;
  3. 了解了定义函数的方法;
  4. 了解了用 if…elif…else 函数控制流程的方法;
  5. 知道了用 while 函数控制流程的方法;
  6. 知道了 print 函数格式化的方法;
  7. 知道了 eval 函数的用法;
  8. 知道了 try…except 函数的用法。

遇到的难点与问题

1. 看完参考资料后找不到入手点

看完手册给的参考资料后,我感觉一头雾水,似乎该知道的都写了,但又不知道怎么完成作业。

最主要的问题是:计算器是 Python 内置的功能,还要怎么实现?难道说“输入 Python 启动 Python 解释器,输入要计算的算式后回车”就算完成任务了?但这怎么用 .py 文件实现呢?

2. 通过搜索完成任务后感觉路数不对

我试着 Google 了一下“Python Calculator”和“Python 计算器”,发现了大量的方案,有相对简单的,也有相对复杂的。

本着先易后难的原则,我参考了《Python Program to Make a Simple Calculator》、《如何在Python 3中做一个简单的计算器程序》、《Python 简单计算器实现》等文章,做了第一个版本,实现了:通过 3 次键盘输入,分别获取两个数字和运算符,然后输出运算结果,另外,在除数为 0 的时候,提示错误。

我把这个版本交给教练后,教练表示这样就算完成任务了,但我觉得路数不大对,主要的原因是:操作不直观、和最初的想法距离较大。

3. 通过搜索找到理想方法后逐步完善

我在 ZingpLiu 的《Python实现计算器》一文中读到了这样一句话:

前几天有个面试题目:计算字符串”1 + (5 - 2) * 3”,结果为10,不能用eval()

这个“不能用eval()”引起了我的注意,我就去查了一下 eval() 是什么,从 Python eval() 函数的介绍页面了解到,eval() 就是把其中的表达式直接给 Python 解释器并输出计算结果,这其实就是我之前想找的方法。

eval() 加上 input()print(),一行代码就可以实现计算器了:

1
print(eval(input()))

我问了一下教练,这样算不算完成任务,教练告诉我也算,“任务不是目的,目的是学习知识”。

不过我觉得,这样完成任务,简洁是简洁了,但还是有些遗憾,比如:

  1. 每次运行只能计算一次,输出结果后就退出了;
  2. 如果输入了错误的内容,会报错直接退出;
  3. 显示的形式不太美观。
  4. 可能有安全隐患。

第一个问题。我一开始参考了上面提到了《如何在Python 3中做一个简单的计算器程序》一文,另外加了个函数 again() 专门用于在计算完成后询问是否要计算其他算式,输入 Y 就重新开始计算,输入 N 就退出。试了几次后觉得这样太繁琐了——每次计算完都得另外按个字母,简洁的方法应该是,计算完直接开始下一次计算,给某个特定输入就退出。
我又看了一遍文档,注意到了 while,搜索之后从《Python While 循环语句》知道了,用 while 1: 可以实现无限循环,结合 ifbreak 就可以实现输入某个特定字母后退出。

第二个问题。我在手册给出的《X分钟速成Y,其中 Y=python3》一文中找到了 try/except 块的介绍,又通过参考《Python 异常处理》一文,外加试错,找了 3 个特定的错误情况,设定输出错误提示并重新开始循环,避免了意外的报错退出。

第三个问题。我通过调整 print() 函数的格式化做了优化。

第四个问题。由于 eval() 是直接把其中的字符串当作输入值传给解释器了,这就可能遇到某些别有用心的人构造特别的输入,从这里入手访问甚至读写网站的文件,这一安全隐患通常是靠限制 eval() 可接受的内容来避免的。我在这里通过 import 引入了 math 模块,再用其构造了字典,继而约束了 eval() 可接受的输入。

总结

  • 编写了一个简单的计算器
  • 用不同方式完成了任务
  • 通过逐步尝试优化代码