目录
1.2.2 安装Visual Studio Code(VS Code)
1.1 Python简介
1.1.1 Python语言优势
近几年,Python受到了广泛关注,即使是非计算机专业的从业人员也希望能够跨行学习Python并运用到自己的专业领域来提高工作效率。
那么到底是什么原因使得Python受到开发者的如此青睐?
简单来说,Python具有三大优势:免费、开源和庞大的第三方库。这三个优势使得Python成为人工智能、网络爬虫、数据分析等领域的首选语言。Python语言是一种面向对象、解释型的程序设计语言,由Guido van Rossum于1989年发明,源代码开放,无论是个人还是商业企业均可以免费使用Python。作为一种高级语言,相对于传统的C++和Java,Python显得更为轻巧,同样的一个任务,使用C++可能需要编写500行代码,使用Java可能需要50行,而使用Python可能只需要5行。另外,选择Python开发项目非常适合初创团队,python拥有庞大的第三方库,能够使得团队用最少的人干最精炼、最有效率的事。
目前,Python涉及的领域几乎涵盖了当前所有热门的IT应用场景,具体见下图。Python不仅已经成为数据分析、人工智能领域必不可少的工具,还被越来越多的企业用于Web搭建,比如说豆瓣、知乎等。
Python社区有一句流行语:人生苦短、我用Python!不管你是什么行业,学点Python一定会对你的工作和生活有所帮助。
1.1.2 用Python开发Web的优势
Python有众多应用方向,堪称“全能型选手”,比如科学计算、数据分析、2D/3D游戏、人工智能和Web开发等。本课程将使用Python来开发一个Web应用(企业门户网站)。如果选择了Web方向,那么就必需了解一种Python Web开发框架,比如Django。下面首先给出一些国内外采用Python和Django框架开发的知名网站,具体如下表所示:
国外 | Quora, Pinterest, Instagram, Google,Youtube, Yahoo Maps, DropBox, Disqus, Washington Post |
国内 | 豆瓣、知乎 |
总体来说,Python Web在国外发展迅猛,例如著名的视频网站Youtube、社交问答网站Quora、图片分享网站Pinterest以及国外最大的搜索网站Google都采用或者部分采用了Python来构建Web。相比于国外,Python Web在国内发展较缓,目前国内采用Python开发的知名网站主要有豆瓣、知乎和网易等。主要原因在于Python在国内的普及时间还不长,众多的Web开发人员还未及时转移到Python Web上来。但是相信随着Python热潮的持续,Python Web的普及进程会不断加快。
学会Python Web,我们可以用来做什么呢?下面举一些例子。
例如,一般地可以采用Python Web建立对外的企业门户网站,也可以开发对内的企业管理软件,如OA系统。Python语言的简洁性可以使得开发这类网站更加便捷、逻辑更加清晰。如果身处游戏企业,可以开发游戏运维平台实现自动化运维。如果在新闻咨询类企业工作,可以开发基于大数据分析、精准投放的付费订阅资讯系统,对于这类网站,基于Python的Django框架是首选。如果想开发电子商务平台,依然可以采用Python进行快速开发。也可以开发Python在线爬虫网站,其中数据爬取、过滤、分析、处理和存储这些常见的Python脚本可以无缝集成在一个Python Web应用里面。当然,现在人工智能如火如荼,可以将人工智能算法部署到Web平台实现如苹果Siri一样的智能互动网站。总之,学好Python Web的作用远远高于制作一个简单的网站。
Django是优秀的Python Web框架之一,拥有完整的Web构建方案,其学习文档和参考资料也非常丰富。学习Django这门Python Web框架可以快速的上手实战,其学习成本相对较低。本课程以一个实际的企业门户网站为例,将在具体实例中讲述Python Web的各个开发要点和难点,通过本课程的系统学习将使您掌握实际的Python Web开发技能。
1.2 安装Python和开发工具
1.2.1 安装Python
Python是一种跨平台语言,因此用Python编写的代码可以在Windows、Linux和Mac上运行。Python是一种高级语言,但是计算机无法直接识别高级语言,计算机只能识别二进制(类似0011 0101这种只有0,1两种值)数据。所以当运行Python程序的时候,需要一个“翻译机”专门负责把高级语言转变成计算机能读懂的二进制语言。这个过程分成两类,第一种是编译型,第二种是解释型。编译型语言在程序执行之前,会先通过编译器对程序执行一个编译的过程,把程序转变成二进制语言。最典型的例子就是C语言。解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行。简单来说,编译型就是将高级语言全部翻译成二进制数据后由计算机一起执行,解释型是一边翻译一边执行。Python就是一种解释型语言。
既然Python是一种解释型语言,那么就需要一个对应的解释器完成上述的二进制转换。这个解释器也就是本节要下载和安装的Python环境了。当然,下载的Python安装包除了解释器以外还附加了一些Python工具,例如开发工具IDLE和对应版本的开发文档等。
Python下载页面网址:Download Python | Python.org。本文下载相对稳定的Python 3.8.10版本(注意,目前最新的Python3.9.7不支持Windows7操作系统)。后面随着Python版本的迭代,当有重大更新时,本博客教程也会尽快更新。
由于我们在Windows上进行代码编写,因此,选择Windows版本的Python进行下载和安装(单击页面上的Windows链接):
然后找到3.8.10对应的windows安装包:
这里选择Windows installer(64-bit)进行下载。 这里注意到该版本已经不再支持XP了,因此,如果读者使用的是XP系统,那么就必须寻找更早期的Python版本。
下载完成后双击该安装包进行安装。
注意上图中一定要将底部的“Add Python 3.8 to PATH”复选框勾上,否则后面就要手动设置环境变量了,会比较麻烦。然后单击选择Customize installation:
默认选择Next:
上图中修改一下安装路径(注意,安装路径中千万不要出现中文)。然后单击Install进行安装:
安装完成后,我们来验证下安装是否正确。
打开cmd命令行工具(开始菜单的搜索框中输入cmd按回车即可打开),然后输入:
python
按回车,如果看到类似下面的效果图就说明Python已经安装正确:
1.2.2 安装Visual Studio Code(VS Code)
VS Code是微软推出的一款免费开源的现代化轻量级代码编辑器,支持几乎所有主流的开发语言,基本功能包括语法高亮、智能代码补全等,同时跨平台支持 Win、Mac 以及 Linux,各平台上均可流畅运行,因此,推出以后受到了开发者的广泛关注和好评。
VS Code由于其非常的轻量,因此使用过程中非常的流畅,对于用户不同的需要,可以自行下载扩展插件Extensions来增强功能。例如,如果想使用Python,那么就安装Python对应的扩展插件,如果想使用C++、PHP、JavaScript等其它语言,那么就安装其它语言对应的插件。
VS Code的下载网址:Visual Studio Code - Code Editing. Redefined。本书代码所用的操作系统是Windows系统,因此下载Windows版本的VS Code,单击Download for Windows进行下载即可:
下载下来后双击安装包然后按照提示进行安装即可。安装完该编辑器软件图标如下所示:
打开该编辑器,首次打开后会提示选择界面风格,这里我们可以按照喜好选择一个即可。
接下来为了能够在VS Code中编辑、调试Python代码,我们需要装个插件,单击左侧“扩展”图标(最后一个图标):
然后,在搜索框中输入python:
可以看到,这时候会出来一堆的python扩展插件,我们选择安装量最大的“Python”进行安装,只需要单击“安装即可”:
这样,我们就可以在VS Code中正常的使用Pyhon了。
接下来,我们简单写段python代码来体验测试下。
首先打开VS Code,选择菜单栏File→New File新建一个空白文件,然后在代码编辑区输入下面的代码:
print('你好,世界')
上述代码用来在控制台输出“你好”。按Ctrl+s组合键保存文件,弹出保存文件对话框,将该文件命名为hello.py,单击保存。按Ctrl+F5组合键运行代码,代码运行后在终端(TERMINAL)会输出“你好,世界”字样,如下所示:
到这里,已经成功的在VS Code中执行了第一行Python代码。
接下来再执行一个稍微复杂点的Python代码,该代码用于完成两个变量的相加并将结果输出,读者通过该示例代码可以进一步体会在VS Code中编写Python代码的便捷,具体如下:
a = 12
b = 32
c = a + b
print(c)
python的语法中每行结尾是不需要符号的,变量的命名也不需要提前申明,这点跟C++、Java等有很大的不同,读者如果不熟悉这些语法也没关系,下面的内容会详细的阐述Python的基础语法。按Ctrl+F5组合键运行上述代码,查看结果是否为44。上述代码中的print是python语言中的语法,类似于c++的cout,其功能就是将结果输出显示。
1.3 基础语法
1.3.1 基本运算
Python可以直接进行加减乘除的数值运算,如下所示:
加法:
print(3+4)
运行结果:7
减法:
print(10-7)
运行结果:3
乘法:
print(3*4)
运行结果:12
除法:
print(10/3)
运行结果:3.33333333333
另外,我们还可以执行一些复杂的数学运算,例如开根号:
import math
print(math.sqrt(4))
上述代码中我们首先使用import命令导入数据工具包math,然后调用math包中的sqrt函数对4进行开根号计算。输出结果:2。
我们还可以进行次方运算,例如想求8的3次方可以使用math包的pow函数:
import math
print(math.pow(8,3))
输出结果:512。
学完这一小节,读者就可以把python当成一个计算器使用了。
接下来我们简单说下python代码的基本格式,从而方便我们掌握整体的python代码风格。
注释:
代码注释就是通过规定的注释符号使某些代码在编译或执行时不起作用,其作用等同于删除这些代码。例如:
# print(100)
print(200)
运行上述代码,发现只会输出200而不会输出100,这是因为输出100的这行语句被“#”注释掉了。
缩进:
Python的语法在形式上与其它语言有明显的不同。Python使用代码的缩进来断行,如果缩进格式不一致,那么就会报错。一般情况下,Python的某一行语句尾部如果有“:”符号,那么就表示下面紧接着的代码需要缩进,所有缩进的代码类似于其它语言中经常使用的大括号。如果在同一级的代码中多添加了空格,这时候VS Code会报编译错误。下面这段代码第二行多了空格,如果直接运行就会报错:
a = 32
b = 56
print(a+b)
一般情况下,Python的每行语句结束时不需要加其它符号,除非是为了说明接下来的内容需要成为一个子段落,一般子段落比上一级段落多缩进4个空格,如下例所示:
x = 1 #1级段落
m = 1 #1级段落
n = 1 #1级段落
if x > 6 : #1级段落
m = 0 #2级段落
n = 1 #2级段落
else: #1级段落
if x < 2: #2级段落
m = 2 #3级段落
n = 1 #3级段落
else: #2级段落
m = 1 #3级段落
n = 0 #3级段落
print(m) #1级段落
print(n) #1级段落
1.3.2 数据类型
- 整数、浮点数、内置常量
与其它语言一样,Python的整数也可以采用不同的进制表示。八进制开头为0o,16进制为0x,二进制为0b,十进制一般不加前缀标志:
a = 12 # 普通10进制数
b = 0x0c # 16进制表示,与a大小相同
c = 0o14 # 8进制表示,与a大小相同
d = 0b1100 # 2进制表示,与a大小相同
浮点数就是常见的小数,一般表示形式如下:
a = 19.0 # 普通方式
b = 19. # 等价于19.0 后面的0可以省略
c = .34 # 等价于0.34 前面的0可以省略
d = 3e5 # 科学计数法 等价于3乘以10的5次方
上面浮点数的写法尤其需要注意一下,与其他语言有点不一样,我们遇到了这样的写法不要觉得陌生。
Python中有一些内置的常量,我们命名变量的时候不能与这些常量重名。下面列出几个在使用Python的过程中经常会遇到的常量:
a = None # "空"常量,用来表示没有值的对象
b = True # 逻辑常量,表示为"真",一般用在条件判断语句中
c = False # 逻辑常量,表示为"假",一般用在条件判断语句中
- 字符串
字符串主要用来表示文本,可以采用单引号、双引号、三个单引号包围来表示,下面列举的三种书写方式是等价的:
a = '你好' # 一般采用的形式
b = "你好" # 字符串中含有单引号时宜采用双引号包围起来表示
c = '''你
好''' # 大段的字符串需要多行表示时可以采用三个单引号包围起来
- 列表、元组、字典
在我们日常操作数据时,经常会遇到一些序列化的数据,例如一张姓名列表或者一张姓名和成绩一一对应的列表等,遇到这种序列化数据格式我们就可以使用python特定的数据类型来处理他们,方便操作。具体Python有3中常见的数据类型:列表、元组和字典。
(1)列表是以方括号“[]”包围的数据集合,括号内成员以逗号“,”分隔,具体操作如下:
a = [3,] #创建只有一个元素的列表
print(a) #输出结果为: [3]
a = [1.2 , 3.4 , 5 , 'hello'] #包含多种数据类型的列表
print(a) #输出结果为: [1.2, 3.4, 5, '你好']
b = a[0] #提取列表的数据元素(元素序号从0开始)
print(b) #输出结果为1.2
python的列表提供了一些方便使用的函数,比如添加数据append、删除成员remove、排序sort等,更多相关内容请读者参考官方说明文档,本教程不再一一举例。
(2)元组功能类似于列表,是采用圆括号“()”包围的数据集合,与列表不同的是元组中的元素不能改变、添加或者删除。示例如下:
a = (3,) #创建只有一个元素的元组
print(a) #输出结果为: (3)
a = (1.2 , 3.4 , 5 , 'hello') #包含多种数据类型的列表
print(a) #输出结果为: (1.2, 3.4, 5, '你好')
b = a[0] #提取元组的数据元素(元素序号从0开始)
print(b) #输出结果为1.2
元组数据创建后不能改变,如果强制改变会报错,如下所示:
a = (1.2 ,) #创建只有一个元素的元组
a[0] = 3 #尝试对元组中的数据进行修改
运行后会报下面的错误:
TypeError: 'tuple' object does not support item assignment
(3)字典:字典是一种以“键:值”成对存在的python数据类型。字典以大括号“{}”包围,与列表的不同在于字典是无序的,使用字典可以通过查找指定的键来寻找特定的值。假设现在一个班级有4名学生,每个学生有一门成绩,那么可以以学生的姓名为键,以成绩为值构造这样一个字典来存储这些数据。采用字典的好处是可以方便的查找任意一名学生的成绩,比如如果想查找某位学生的成绩只需要采用下面的代码:
gradeDic = {'小明':85 , '小红':98 , '韩梅梅':87 , '李雷': 65}
grade = gradeDic['小红']
print(grade) #输出结果为: 98
在后面课程中采用Python开发Web应用时经常会遇到一种数据格式:JSON字符串。JSON是一种轻量级的数据交换格局,方便在不同平台上处理其中包含的数据。JSON在表现形式上与Python的字典结构非常相似,如下所示:
gradeJson = {"小明":"85","小红":"98","韩梅梅":"87", "李雷": "65"}
尽管形式相同,但是并不一样。实际上JSON就是Python字典的字符串表示,字典有很多内置函数,有多种调用方法,而JSON仅仅是数据打包的一种格式,并不像字典具备操作性。另外,JSON在格式上有一些限制,比如JSON的格式要求必须且只能使用双引号作为键或者值的边界符号,不能使用单引号,但字典没有这种限制。
1.3.3 控制语句
计算机在执行代码时一般分为三种情况:顺序执行、选择部分代码执行、循环执行。事实证明,计算机实现的任何一个功能都可以采用这三种结构进行解决,这三种控制结构存在于目前几乎所有主流的开发语言中,包括C、C++、Java、JavaScript等,当然也包括Python。Python用于流程控制的语句主要有if、for和while,这些控制语句均从C语言借鉴过来。事实上,Python的底层就是由C语言实现的。
(1)if 条件控制
在实际编程时,经常需要根据程序执行过程中的某个条件来选择是否执行某一部分代码,这时候就要使用if语句。Python的if语法较为简单,其关键字是if(如果)、elif(或者如果)、else(或者)。一个if复合语句中可以有多个elif。具体见下例:
x = int(input("请输入一个整数 : "))
if x > 0:
print (str(x)+" > 0")
elif x < 0:
print (str(x), " < 0")
else:
print (str(x), " = 0")
上述示例中,首先通过input函数在控制台让用户输入一个整数,用户输入后按回车键即可将输入的数值赋值给变量x。然后进入条件判断语句,当x大于0的时候,输出“x>0”。这里在输出部分做了一次强转换,将整数x强制转换成字符串然后再与后面的字符串“ >0”拼接。当x<0时,输出“x<0”。否则(既不大于0也不小于0)输出“x=0”。
(2)for 循环
Python的for语句和C语言中的for语句是有区别的,C语言的for语句有循环变量初始语句、变化语句以及一个循环结束条件语句。C语言的for循环语句较为灵活,而Python的for语句就是在一个序列(Sequence)上进行遍历。基本语法形式为:for item in sequence,可以理解为“对序列中的元素,逐个执行某种操作”。具体的参考如下:
words = ["王强", "小明", "张磊"]
for word in words:
print(word + '\r\n') # \r\n可以实现回车换行
上述代码实现对列表words中的每个元素逐个进行输出。
如果需要根据循环中的序号进行操作,可以采用range函数。range函数会创建一个可迭代对象,用于在for循环中操控序号。可迭代对象是Python里面的重要概念,从字面意思理解凡是可以迭代的对象即为可迭代对象,这里可以将可迭代对象暂时看成是列表。比如,当使用range(1,5)的时候类似于返回一个列表,其内容为[1,2,3,4]。实际情况下使用range函数并不会在内存中真正产生一个列表对象,这样做主要是为了节约内存空间。通过使用range函数,可以上例进行改写:
words = ["王强", "小明", "张磊"]
for i in range(len(words)):
print(words[i] + '\r\n') # \r\n可以实现回车换行
(3)while 循环
Python的for语句以遍历对象的方式构造循环,需要直接或者间接的得到迭代内容才能使用for语句,但是有时候需要在某种不确定数据的情况下进行循环,这时候就需要使用while循环。在数据未知的情况下无法使用for循环进行迭代,这时候需要采用while循环设置好数据的生成规则就可以生成无穷的数据,具体如下所示,代码中限定生成的数据个数不超过10个:
a, b = 0, 1
fib = []
while len(fib) < 10:
a, b = b, a+b
fib.append(b)
print(fib)
上述代码是一个经典的Fibonacci数列构造问题(当前值等于前面两个值相加),输出结果为:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
(4) break和continue
break和continue也是从C语言借鉴过来的,而且意义也一样。break表示跳出当层循环,continue表示跳过本轮循环开始执行下一轮。循环语句for和while也可以有else,这是当循环完成,也就是没有被break打破循环的情况才会执行的语句块。下例采用break和continue语句来找出2~19中的质数:
factor = []
for n in range(2, 20):
for x in range(2, n):
if n % x == 0: #判断能否被2到自身之间的整数整除
print('%d不是质数' % (n))
break
#直接退出当前循环,执行后n=n+1
else:
continue
#直接跳过本次循环,执行后x=x+1
else:
factor.append(n)
print(factor)
输出结果为:
4不是质数
6不是质数
8不是质数
9不是质数
10不是质数
12不是质数
14不是质数
15不是质数
16不是质数
18不是质数
[2, 3, 5, 7, 11, 13, 17, 19]
1.3.4 函数
一般情况下编写代码是根据业务逻辑从上到下实现功能,往往需用一长段代码来实现指定功能。为了能够实现代码的重复利用,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处。这种编程方式虽然可以应付一般性问题,但是不能对付大多数问题。比如如果想要计算圆的周长(周长 = 2 * π * 半径),可以采用如下重复代码段的方式实现。
r1 = 12.3
r2 = 9.1
r3 = 64.21
s1 = 2 * 3.14 * r1 # 计算第1个圆的周长
s2 = 2 * 3.14 * r2 # 计算第2个圆的周长
s3 = 2 * 3.14 * r3 # 计算第3个圆的周长
上述代码中,重复了2遍几乎一样的步骤用来计算圆周长。是否可以根据公式避免这种麻烦的情况,使得依然能够完成相同的功能?答案是可以的。可以将重复的代码段编成一个完整的函数用来重复调用。有了函数,就不再需要每次写s = 2 * 3.14 * r,而是写成更有意义的函数调用形式,例如s = perimeter_of_circle(r),其中函数perimeter_of_circle本身只需要写一次,就可以多次调用。
Python不但能非常灵活地定义函数,而且本身内置了很多有用的函数,可以直接调用,在前面我们已经使用math函数进行过尝试。函数最大的优点就是可以增强代码的重用性和可读性。
(1)基本调用形式
函数通过关键字def进行声明,函数内执行功能的代码不需要使用类似C语言的大括号{}来包围,而是通过Python的缩进语法进行表示。针对之前计算圆周长的例子,可以定义一个perimeter_of_circle函数,函数内只需要传入一个参数半径r,函数内计算2 * 3.14 * r并返回计算结果即可,具体见下例:
def perimeter_of_circle(r): #计算圆周长函数
s = 2 * 3.14 * r
return s
r1 = 12.3
s1 = perimeter_of_circle(r1) #调用函数
print(s1) # 输出 77.24400000000001
Python函数也支持默认参数,即可以给函数的参数指定默认值。当该参数没有传入相应的值时,该参数就使用默认值。例如上例中当没有传入参数时,默认半径设置为1,实现方式如下:
def perimeter_of_circle(r = 1): # 计算圆周长函数
s = 2 * 3.14 * r
return s
s1 = perimeter_of_circle() # 调用函数,不传入任何参数
print(s1) # 输出6.28
(2)可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。以一个经典数学题为例:给定一组数字a,b,c……,请计算a + b + c + ……。要定义出这个函数,首先必须确定输入的参数。由于参数个数不确定,因此我们可以使用可变参数:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n
return sum
在调用的时候直接传入数值,例如calc(1, 2, 3)。
(3)关键字参数
可变参数允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个元组。而关键字参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个字典,即传入键值对组合。关键字参数可以扩展函数的功能,比如,在Web项目的注册功能中,必填项一般有用户名(name)和密码(pwd),这两个参数肯定是可以获得的,可以使用普通参数形式进行传递,但是,如果注册者愿意提供更多的信息,比如年龄(age)、 邮箱(email)等,这些可选项就可以利用关键字参数来扩展注册函数功能。具体如下例所示:
def register(name, pwd, **kw):
if 'email' in kw: # 字典中有email参数
print('邮箱是 '+kw['email'] +'\r\n')
if 'age' in kw: # 字典中有age参数
print('年龄是 '+kw['age'] + '\r\n')
name = '小明'
pwd = '123456'
extra = {'email': 'xiaoming@126.com', 'age': '13'}
register(name,pwd, **extra)
最后总结下,在Python Web开发中会经常遇到函数的可变参数和关键字参数这种形式,在遇到此类函数时要牢记*kw这种参数形式是用来传递可变参数的,而**kw这种参数形式是用来传递字典的。
1.3.5 面向对象
前面几节内容从本质上来说都是属于面向过程的编程,即以任务为导向,而Python语言其实也是一种面向对象的编程语言。面向对象是当前大多数编程语言均具备的特性,比如C++、Java和JavaScript等,它们都属于面向对象编程语言。在面向对象编程时,需要理解什么是程序中的对象、什么是类、类的使用方式和类的继承等基本概念和方法。
面向过程的程序设计其核心是过程,采用流水线式思维,整个编程方式围绕解决问题的步骤展开,类似于精心设计一条流水线,需要提前考虑周全什么时候处理什么东西并且设计好每一个处理步骤。面向过程的编程方式可以降低写程序的复杂度,只需要顺着执行的步骤,堆叠代码即可完成功能。但是其缺点也显而易见,一套流水线或者流程就是用来解决一个任务,如果任务有变更或者有新的需求需要加入,那么用面向过程编写的代码往往牵一发而动全身需要大量更改,整个项目难以维护。
与面向过程不同,面向对象的程序设计其核心是对象,所有的处理函数和关联变量都被封装起来,最终以一个个的对象进行呈现和操作。在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。面向对象编程可以很好的解决程序的扩展性,对某一个对象单独修改,会立刻反映到整个体系中。比如游戏开发时,如果将每一个游戏人物作为对象,那么当需要对这个人物添加额外属性的时候采用对象编程可以很容易的完成新属性的添加。下面举一个简单例子来说明面向过程和面向对象在处理方式上的不同之处。
假设有一个任务需要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用字典来存储每个学生的姓名和对应的成绩:
std1 = { 'name': '小明', 'score': 98 }
std2 = { 'name': '小红', 'score': 81 }
如果需要输出某个学生的成绩,可以通过相应的函数进行操作:
def print_score(std):
print('%s: %s' % (std['name'], std['score']))
如果采用面向对象的程序设计思想,那么首先思考的不是程序的执行流程,而是学生(Student)这种数据类型应该被视为一个对象,这个对象拥有姓名(name)和成绩(score)这两个属性(Property)。如果要输出一个学生的成绩,首先必须创建出这个学生对应的对象,然后,用这个对象调用封装在自己内部的成绩输出函数print_score,把自己的成绩数据显示出来。具体代码实现见下例:
类的构造:
class Student(object):
def __init__(self, name, score): # 注意此处是双下划线
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
在Python中,定义类是通过class关键字表示,class后面紧接着是类名,即Student,后面是(object),表示该类是从哪个类继承下来的,在类中有两个函数:__init__初始化函数(注意这里有两个下划线),可以将name、score等值在对象创建时从外部传入到类的内部变量中。如果读者熟悉C++、Java等语言,那么这个__init__方法等价于构造函数的作用。注意到__init__方法的第一个参数永远是self,表示创建的对象本身。另一个函数print_score和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且调用时不用传递该参数。除此之外,类的方法和普通函数没有区别。
封装完后可以按照下述代码进行调用:
std1 = Student('小明', 98)
std2 = Student('小红', 81)
std1.print_score()
std2.print_score()
上述例子中,尽管采用面向对象的编程方式看着更复杂,但是当项目后期变得庞大时采用面向对象这种编程方式可以使得项目维护更加容易、结构更加清晰。
python的类使用还要很多复杂的方法,包括继承多重继承等,这些概念我们不再深入学习,等后面真实案例中遇到了我们再讲解。
1.3.6 模块和包
在前面已经介绍并使用过Python的math模块用来执行一些高级的数学运算。模块本质上就是包含函数和其它语句的Python脚本文件,以“.py”为后缀名。用作模块的Python函数和在同一个Python文件中定义的函数没有区别,只是把这些功能函数拆分在了不同的Python文件中,需要的时候通过模块导入文件中的这些函数。Python模块的导入有三种方式,下面依然以math模块为例作介绍。
(1)采用“import 模块名”的方式:
import math
a = math.sqrt(4)
print(a)
采用上述方式会将math模块中的所有函数全部导入进来。
(2)采用“from 模块名 import 函数”的方式:
from math import sqrt
a = sqrt(4)
print(a)
采用这种方式可以将指定模块中的指定函数导入进来,在函数调用的时候函数名前不需要加上模块。采用from语句还有一种常见的形式如下:
from math import *
a = sqrt(4)
print(a)
采用这种方式同样可以导入math模块中的所有函数,并且在调用的时候不需要添加模块名。
(3)采用“import 模块名 as 新模块名”的方式:
import math as ma
a = ma.sqrt(4)
print(a)
这种方式主要是用来避免模块之间函数名冲突,即在模块导入的过程中同时对模块重新命名,调用的时候也采用新的模块名来调用。
模块以Python文件的形式组织在同一个目录下进行调用,当应用程序或者项目具有较多的功能模块时,就需要对模块进一步的进行细化管理,将实现特定功能的模块文件放在同一个文件夹下,这个文件夹就是包。
Python包从本质上来说就是一个文件夹,与一般的文件夹不同之处在于包中必须包含一个名为__init__.py的文件。__init__.py文件可以是一个空文件,仅用于表示该文件夹是一个包。在第1章创建Django项目时已经遇到过这种包的处理方式。文件夹可以实现嵌套,同样的包也可以实现嵌套,这种嵌套的包在调用时采用“.”符号进行递进式的导入。
Python拥有丰富的第三方包和模块可供调用,只需要使用下面的命令进行安装即可。
pip install 包名
1.4 案例1:学生Excel成绩表格自动统计
1.4.1 任务说明
我们经常在工作中需要利用excel进行数据统计,一种比较简单的方法就是利用excel自带的命令进行编程,但是这种编程方式不够直观、编程效率低、功能有限。现在有了python,我们就可以利用python强大的第三方库进行excel数据操作。本小节任务就是使用python来实现一个学生excel成绩表格的统计。
任务说明:给定一份excel表格如下图所示,需要利用python将每位学生的平均分计算得出并填入到“平均分”那一列;同时还有个额外要求:如果某位学生的平均分低于60分,其平均分用红色字体标出;
1.4.2 案例实战
这个案例任务的关键在于我们需要通过python获取到excel工作簿中每个单元的值并且能够将值写入到某个单元,同时能够修改某个单元格的属性(字体颜色等),只要能实现这个步骤,那么计算均值之类的操作也就能够轻而易举的实现了。python本身处理excel是比较困难的,幸运的是,python拥有众多的第三方库,其中就有专门用于处理excel的python库:openpyxl。使用这个库我们就可以方便的读取excel的内容了。
具体的,我们可以使用下面的命令进行安装:
pip install openpyxl
另外,我们需要使用求均值操作,我们可以安装一个更强大的数值计算工具包numpy:
pip install numpy
好了,到这里环境装完了。
我们新建一个python脚本main.py,并且将这个excel表格放置在与main.py同目录下,然后编辑main.py,代码实现思路:
(1)导入相关库;
(2)从表格的第3行开始一直遍历到15行,提取出每行的第5列(语文成绩)、第6列(数学成绩)、第7列(英语成绩),然后调用numpy库的mean函数计算均值,然后将结果写入打第8列;
详细代码如下:
# 导入库
from openpyxl import load_workbook
import numpy as np
# 打开文件
excel = load_workbook('student.xlsx')
# 获取工作簿
table = excel.get_sheet_by_name('score')
# 循环取值
for i in range(3,16):
chinese_score = table.cell(row=i,column=5).value
math_score = table.cell(row=i,column=6).value
english_score = table.cell(row=i,column=7).value
mean_score = np.mean([chinese_score,math_score,english_score])
table.cell(row=i,column=8).value = round(mean_score)
# 保存结果
excel.save(filename='student_new.xlsx')
print('完成')
最后,修改后的excel表格会单独保存为student_new.xlsx。(注意:excel文件名称和工作簿名称中不要出现中文)。上述代码中,使用了round函数,用于对浮点数均值进行四舍五入取整,这样显示更符合实际要求。
打开新生成的student_new.xlsx,如下所示:
接下来我们继续完善上述代码,判断均值是否小于60,小于60的用红色字体显示。 实现时,只需要利用openpyxl.styles的Font类,修改这个类的颜色属性并将该类的实例赋值给指定单元格,即可改变单元格的颜色属性。
完整代码如下:
# 导入库
from openpyxl import load_workbook
from openpyxl.styles import Font
import numpy as np
# 打开文件
excel = load_workbook('student.xlsx')
# 获取工作簿
table = excel.get_sheet_by_name('score')
# 循环取值
for i in range(3,16):
chinese_score = table.cell(row=i,column=5).value
math_score = table.cell(row=i,column=6).value
english_score = table.cell(row=i,column=7).value
mean_score = np.mean([chinese_score,math_score,english_score])
table.cell(row=i,column=8).value = round(mean_score)
if round(mean_score) < 60: # 设置字体样式
font = Font(color='ff0000') # 红色
table.cell(row=i, column=8).font = font
# 保存结果
excel.save(filename='student_new.xlsx')
print('完成')
最终效果如下所示:
本节课完整代码和数据下载地址如下:
百度网盘:https://pan.baidu.com/s/1170YX5lA2bGm-Q0Ts_TYPA
提取码:m0p3
本节课内容比较基础,重点讲解了Python语法,最后用一个比较实用的案例来巩固所学的Python基础知识。下节课开始将会正式进入Python Web领域,逐步开发一套完整的企业门户网站。
课程介绍链接:Python Web企业门户网站—系列博客教程介绍_冰海的博客-CSDN博客_python web开发从入门到实战