第十九章 趣味编程

第十九章 趣味编程

本章将介绍一些通用的Python编程指南。

为何要有趣

Python有趣的地方之一就是让用户的编程效率非常高效。
极限编程是一种软件开发方法

编程柔术

python的灵活性描述
原型设计Python的优点之一是让你能够快速地编写程序。要更深入地了解面临的问题,编写原型程序是一种很好的办法。
配置灵活性形式多样。配置旨在让程序的某些方面修改起来更容易——对你和用户来说都如此。
自动化测试能够轻松地修改程序,有了测试后,就能确信程序在修改后也能正确地运行。

原型设计

原型(prototype)指的是尝试性实现,即一个模型。它实现了最终程序的主要功能,但在后期可能需要重写,也可能不用重写。通常,最初的原型都能变成可行的程序。

Python的优点在于,使用它编写模型的投入很少,因此完全可以弃之不用。

每个项目都有两个实现。
第一个实现是摸着石头过河:拼凑出一个能够解决问题(或部分问题)的程序,以便了解需要的组件以及对优秀解决方案的要求。在这个过程中,最重要的可能就是看到程序的各种缺陷。基于这些新的认识,再次尝试解决面临的问题,而此时人们的判断力和洞察力可能更强。

配置

重温抽象这一重要原则。第6章和第7章介绍了如何提高代码的抽象程度,这是通过将代码放在函数和方法中并将较大的结构隐藏在类中实现的。

另一种简单得多的提高程序抽象程度的方式:提取代码中的符号常量(symbolic constant)。

提取常量

常量,指的是内置的字面量值,如数、字符串和列表。
对于这些值,可将其存储在全局变量中,而不在程序中反复输入它们。

全局变量存在的问题仅在被修改时才会呈现出来,因为很难确定代码的哪部分修改了哪些全局变量。

一种高效的方法是:不去修改这些全局变量,而是将它们作为常量(即符号常量)。
要指出变量被视为符号常量,可遵循一种特殊的命名约定:只在变量名中使用大写字母并用下划线分隔单词。

计算圆的面积和周长
在程序开头包含代码行PI = 3.14,然后使用名称PI而不是数本身。这样,以后要使用更精确的值时,只需修改这行代码即可。每当需要输入常量(如数字42或字符串Hello,world!)多次时,都应考虑将其存储在全局变量中。

from math import pi
pi = 3.14#若需要修改pi的值,可以在此处修改即可
r=input("please input the r")
area = pi*float(r)*float(r)
circumference = pi*2*float(r)
print(float(area))
print(float(circumference))'''#运行结果为:
please input the r2
12.56
12.56
'''

配置文件

虽然可以为自己方便而提取常量,但有些常量必须暴露给用户。
例如,如果用户不喜欢你编写的GUI程序的背景色,可能应该允许他们使用其他颜色;对于你开发的街机游戏,可让用户决定启动时显示的问候消息;对于你开发的Web浏览器,可让用户决定默认显示的起始页面。

可将这些配置变量放在独立的文件中,而不将它们放在模块开头。
为此,最简单的方式是专门为配置创建一个模块

from config import PI

如上述代码所示,如果要修改PI的值,只需编辑config.py,而不用在代码中搜索。

使用配置文件有利有弊。一方面,配置很有用;但另一方面,使用针对整个项目的中央共享变量库可能降低项目的模块化程度(即增大耦合程度)。因此,使用配置文件时,务必不要破坏抽象(如封装)。

另一种方法是使用标准库模块configparser,从而可在配置文件中使用标准格式。

必须使用[files]、[colors]等标题将配置文件分成几部分(section)。
标题的名称可随便指定,但必须将它们用方括号括起。

一个简单的配置文件(area.ini)

[numbers]
pi: 3.1415926535897931[messages]
greeting: Welcome to the area calculation program!
question: Please enter the radius: 
result_message: The area is

一个使用ConfigParser的程序

from configparser import ConfigParserCONFIGFILE = "area.ini"config = ConfigParser() 
# 读取配置文件:
config.read(CONFIGFILE) # 打印默认问候语(greeting):
# 在messages部分查找问候语:
print(config['messages'].get('greeting')) # 使用配置文件中的提示(question)让用户输入半径:
radius = float(input(config['messages'].get('question') + ' ')) # 打印配置文件中的结果消息(result_message);
# 以空格结束以便接着在当前行打印:
print(config['messages'].get('result_message'), end=' ') # getfloat()将获取的值转换为浮点数:
print(config['numbers'].getfloat('pi') * radius**2)

日志

日志大致上就是收集与程序运行相关的数据,供你事后进行研究或积累。
print语句是一种简单的日志形式。
标准库中的日志模块为logging

一个使用模块logging的程序

import logging
logging.basicConfig(level=logging.INFO, filename='mylog.log') 
logging.info('Starting program') 
logging.info('Trying to divide 1 by 0') 
print(1 / 0)
logging.info('The division succeeded') 
logging.info('Ending program')'''#运行结果为:
import logging
logging.basicConfig(level=logging.INFO, filename='mylog.log') 
logging.info('Starting program') 
logging.info('Trying to divide 1 by 0') 
print(1 / 0)
logging.info('The division succeeded') 
logging.info('Ending program')
'''

运行这个程序时,将生成下面的日志文件(mylog.log):
在这里插入图片描述
日志内容如下:

INFO:root:Starting program 
INFO:root:Trying to divide 1 by 0

在这里插入图片描述
试图将1除以0后什么都没有记录下来,因为这种错误将导致程序终止。这是一种简单的错误,你可根据程序崩溃时打印的异常来跟踪确定问题出在什么地方。
不会导致程序终止、而只是让它行为异常的bug是最难查找的,但通过查看详尽的日志文件也许能够帮助你找出问题出在什么地方。

这个示例中的日志文件并不是很详细,但通过合理地配置模块logging,可让日志以你希望的方式运行。下面是几个这样的示例。

  • 记录不同类型的条目(信息、调试信息、警告、自定义类型等)。默认情况下,只记录警告。(这就是在一个使用模块logging的程序中显式地将level设置为logging.INFO的原因所在。)
  • 只记录与程序特定部分相关的条目。
  • 记录有关时间、日期等方面的信息。
  • 记录到其他位置,如套接字。
  • 配置日志器,将一些或大部分日志过滤掉,这样无需重写程序就能获得所需的日志信息。模块logging非常复杂,文档中还提供了其他很多相关的信息。

小结

概念描述
灵活性设计和编程时,应以灵活性为目标。随着对所面临问题了解得越来越深入,你应心甘情愿乃至随时准备修改程序的方方面面,不要固守最初的想法。
原型设计要深入了解问题和可能的实现方案,一个重要的技巧是编写程序的简化版本,以了解它是如何工作的。使用Python编写原型非常容易,使用众多其他语言编写一个原型所需的时间足以让你用Python编写多个原型。即便如此,除非万不得已,否则不要推倒重来,因为重构通常是更佳的解决方案。
配置通过提取程序中的常量,可让以后修改程序变得更容易。通过将这些常量放在配置文件中,让用户能够配置程序,使其按自己希望的方式行事。通过使用环境变量和命令行选项,可进一步提高程序的可配置性。
日志日志对找出程序存在的问题或监视其行为大有裨益。你可自己动手使用print语句实现简单的日志,但最安全的做法是使用标准库中的模块logging。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android按钮在容器下方,使用flex布局解决安卓手机上固定在底部的按钮,在键盘弹起后挡住input输入框的问题...

移动端经常会出现,一个表单里面,确定按钮固定在底部这样的布局,一般会让按钮absolute或者fixed,这样在ios上没有问题,但是在安卓手机上,当表单里面的input输入框获得焦点的时候,按钮会挡在表单上…

dbms支持哪几种数据模型_DBMS中不同类型的数据模型

dbms支持哪几种数据模型资料模型 (Data Model) A data model is a model that defines in which format the data are represented and accessed. Data model mainly defines some of the data elements and relationships that exist between them. 数据模型是定义数据以哪种格…

JS 数组迭代方法

var arr [3,4,5,6,7,"a"]; var isNum function(elem,index,AAA){ return !isNaN(elem);} var toUpperCase function(elem){ return String.prototype.toUpperCase.apply(elem);} var print function(elem,index){ console.log(index"."elem);} /*对数组…

php开源问答_PHP基础知识能力问答

php开源问答This section contains Aptitude Questions and Answers on PHP Basics. 本部分包含有关PHP基础知识的 Aptitude问题和解答。 1) There are the following statements that are given below, which of them are correct PHP? PHP stands for the Preprocessor Hom…

【数据结构基础笔记】【顺序表】

代码参考《妙趣横生的算法.C语言实现》 文章目录前言1、创建顺序表2、顺序表插入元素3、顺序表删除元素4、顺序表实例分析1、静态2、动态5、顺序表总结前言 本章总结:从静态和动态分别进行顺序表的创建、插入、删除、以及实例分析 1、创建顺序表 1、静态地生成一张…

ubuntu安装oracle unzip: No such file or directory

$ln -s /usr/bin/unzip /你的oracle11安装目录/install/unzip$sudo chmod 777 /usr/bin/unzip转载于:https://www.cnblogs.com/qm4050/archive/2011/08/25/2241466.html

一、网络爬虫概述

1,浏览器与网络爬虫的区别 答: 对于浏览器而言:浏览器打开一个网站,会对网站服务器发送一个request请求,服务器收到该请求之后,会给浏览器一个respond响应,该响应携带很多数据,之后…

百度android广告sdk下载,IS_Freedom

美数广告 SDK接入流程1.嵌入广告SDK将 sdk-android-demo/app/libs 中的 meishu-sdk_xxx_release.aar、open_ad_sdk_xxx.aar、Baidu_MobAds_SDK-release-xxx.aar、GDTSDK.unionNormal.xxx.aar、msa_mdid_1.0.13 拷贝到项目的 libs 下,对应的 build.gradle 文件里面添…

关于《加密与解密》的读后感----对dump脱壳的一点思考

偶然翻了一下手机日历,原来今天是夏至啊,时间过的真快。ISCC的比赛已经持续了2个多月了,我也跟着比赛的那些题目学了2个月.......虽然过程很辛苦,但感觉还是很幸运的,能在大三的时候遇到ISCC,不管怎样&…

java vector_Java Vector elements()方法与示例

java vector向量类elements()方法 (Vector Class elements() method) elements() method is available in java.util package. elements()方法在java.util包中可用。 elements() method is used to get an enumeration of the elements that exist in this Vector. elements()方…

【数据结构基础笔记】【链表】

代码参考《妙趣横生的算法.C语言实现》 文章目录前言1、链表基础2、创建一个链表3、插入结点4、删除结点5、销毁链表6、实例分析前言 本章总结:链表的定义、创建、销毁,结点的插入与删除 1、链表基础 链表的物理存储结构是用一组地址任意的存储单元存储…

动态添加,删除行之心理测试系统

动态添加,删除行之考试系统 数据库设计: xl_option 题目选项 20090105134755404(编号) 20090105134904421(外键) 比较符合(选项内容) ②(选项标号) 2(选项分值) xl_subject 题目信息 20090105134943608(编号&#xff…

android bitmap裁剪中间,Android裁剪中心位图

虽然上面的大多数答案提供了一种方法来实现这一点,但已经有一种内置的方法来实现这一点,它是一行代码(ThumbnailUtils.extractThumbnail())int dimension getSquareCropDimensionForBitmap(bitmap);bitmap ThumbnailUtils.extractThumbnail(bitmap, di…

二、request请求库

一、requests介绍与安装 1,requests介绍 答:requests是一个优雅且简单的Python HTTP请求库 2,requests作用 答:requests的作用是发送请求获取响应数据 3,requests安装 答:pip install requests 二、…

Java Vector Capacity()方法与示例

向量类的Capacity()方法 (Vector Class capacity() method) capacity() method is available in java.util package. Capacity()方法在java.util包中可用。 capacity() method is used to return the current capacity (i.e. initially, how many object exists) of this Vecto…

MFC和GTK的区别

关键技术 http://blog.csdn.net/master_max/article/details/1540204 MFC和GTK的区别?? 1.  两者都是基于面向对象设计的。尽管MFC是用C写的,而GTK是用C写的,但思想都是面向对象的。GTK使用glib的对象机制,由于用C写…

视频图像质量评价

目录1、人眼视觉特性1、眼的适应性2、对比灵敏度3、空间分辨率和时间分辨率4、马赫效应5、可见度阈值2、图像质量测度3、图像评价方法4、图像评价方法的优劣1、人眼视觉特性 1、眼的适应性 暗适应性:从亮环境到暗环境,适应暗环境的特性 亮适应性&#…

鸿蒙科技与文化,数字阅读 | “华为鸿蒙”:当现代科技遇到古典文化

华为事件愈演愈烈。海思芯片 20 年 " 备胎 " 终转正,那么操作系统呢?最近,华为为自主研发的操作系统注册商标—— " 鸿蒙 ",引发了关于华为注册整本《山海经》的热烈讨论,很多人的朋友圈&#xff…

三、Beautiful Soup解析库

一、Beautiful Soup介绍与安装 1,Beautiful Soup介绍 答:Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库 2,Beautiful Soup安装 答:安装Beautiful Soup 4:pip install bs4 安装lxml:pip…

strictmath_Java StrictMath sqrt()方法与示例

strictmathStrictMath类sqrt()方法 (StrictMath Class sqrt() method) sqrt() Method is available in java.lang package. sqrt()方法在java.lang包中可用。 sqrt() Method is used to find the square root of the given parameter in the method. Here, "sqrt" st…