60分钟

第10章 Python程序开发基础

【学习目标】

1.知识目标

了解Python程序开发过程。

掌握Python语言概念。

掌握常用第三方库的使用。

掌握Python调用云API的用途。

2.技能目标

安装Python的开发工具。

编写简单的Python程序。

调试程序。

编译程序

【认证考点】

了解Python程序开发过程。

认识Python语言相关概念。

能够编写简单的Python程序。

能够编译、运行Python程序。

基本读懂Python程序。

能够编写Python程序调用腾讯云API。

项目引导:Python调用云API管理云资源

【项目描述】

腾讯的Python SDK是云API平台的配套工具,用户可以通过编写Python程序来实现诸如查看CVM实例及机型列表、查看VPC下的云主机实例列表和查看子网列表等功能。完成该项目需要安装与配置Python语言的开发环境、熟悉Python基础语法、安装腾讯云SDK、编写Python程序代码和调试及运行代码,经过上述过程才能完成该项目。

知识储备

10.1 Python语言概述

Python英文本义是指“蟒蛇”,是一门跨平台、开源、免费的解释型高级动态编程语言,支持命令式编程、函数式编程,并且完全支持面向对象程序设计,语法简洁清晰。

10.1.1 Python版本介绍

在Python的发展过程中,形成了Python 2.x和Python 3.x两个不同系列的版本,Python 3.x版本相对于Python 2.x版本,是一个较大的升级,Python 3.x在设计的时候没有考虑向下兼容,为了满足不同Python用户的需求,目前是Python 2.x和Python 3.x两个版本并存。2020年1月1日,官方宣布停止Python 2的更新,Python 2.7被确定为最后一个Python 2.x版本,本章节内容主要针对Python 3.x版本进行讲解。

10.1.2 Python的下载和安装

用户可以在网址“https://www.python.org”,下载Python开发环境的安装程序,下载页面如图10-1-1所示。本章节所用操作系统为Windows 10,使用Python 3.7.0的64位开发环境。

图10-1-1 Python开发环境下载页面

用户双击打开下载的Python开发环境的安装程序Python3.7.0.exe,将启动安装向导如图10-1-2所示,选中“ Add Python 3.7 to PATH”复选框,将Python的可执行文件路径添加到Windows操作系统的环境变量PATH中,以方便在开发中启动Python开发环境。

图10-1-2 Python开发环境安装向导

在Windows 7操作系统下,Python默认的安装路径是C:\Users\Administrator\AppData\Local\Programs\Python,如果用户想要自定义Python安装环境的安装路径,可以在图10-1-2中选中“ Customize installation”选项,并选择需要安装的具体路径。安装成功后的界面如图10-1-3所示。

图10-1-3 Python安装成功界面

Windows系统的“开始”菜单中会显示图10-1-4所示的Python命令,这些命令的具体含义如下:

“IDLE(Python3.7 64-bit)”—启动Python自带的集成开发环境IDLE。

“Python3.7(64-bit)”—将以命令行的方式启动Python的解释器。

“Python3.7 Manuals(64-bit)”—打开Python的帮助文档。

“Python 3.7 Module Docs(64-bit)”—将以内置服务器的方式打开Python模块的帮助文档。

图10-1-4 Python命令

10.1.3 内置的IDLE集成开发工具

Python是一种脚本语言,开发Python程序首先要在文本编辑工具中书写Python程序,文本编辑工具可以是Windows系统自带的记事本工具,然后由Python解释器执行。Python开发环境自带的IDLE是一个集成开发工具(Integrated Development Environment,IDE),其启动文件是idle.bat,位于安装目录的Lib\idlelib文件夹下。用户可以在“开始”菜单的“所有程序”中选择Python3.7的IDLE命令,即可打开IDLE窗口,如图10-1-5所示。

图10-1-5 IDLE窗口界面

10.1.4 pip安装与使用

pip是Python包管理工具,pip可以运行在Unix/Linux或Windows平台上,Python 2.7.9或Python 3.4以上版本都自带pip工具。用户可以在cmd命令行中通过以下命令来判断是否已安装了pip工具。

pip --version

如果用户还未安装,则在cmd命令行中可以使用以下方法来安装pip工具。

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py  # 下载安装脚本
sudo python get-pip.py  # 运行安装脚本

pip主要命令有:

install—安装包

download—下载包

uninstall—卸载包

freeze—以requirements的格式输出已安装的包

list—列出已安装的包

在cmd命令行中可以输入相应命令,具体示例如下。

pip install packageName      # 安装最新版本
pip install packageName==1.0.8   # 安装指定版本
pip install 'packageName>=1.0.8'   # 指定安装的最小版本
pip uninstall packageName      # 卸载某个包

10.1.5 PyCharm集成开发工具

PyCharm是JetBrains公司开发的集成开发工具(IDE),具有典型集成开发工具(IDE)的多种功能,如程序调试、语法高亮、工程管理、代码跳转、智能提示、自动完成、单元测试、版本控制等。

1.PyCharm的下载和安装

访问PyCharm的官方网址,进入PyCharm的下载页面,如图10-1-6所示,用户可以根据自己的操作系统平台下载不同版本的PyCharm。Professional是需要付费的版本,它提供Python IDE的所有功能,支持Web开发,适合用来开发大型Python的应用项目。Community是轻量级的Python IDE,是一款免费和开源的版本,只支持Python开发,适合初学者使用。

图10-1-6 PyCharm下载页面

安装PyCharm的过程十分简单,用户只要按照安装向导的提示逐步安装即可,安装过程中选择安装路径的界面如图10-1-7所示。

图10-1-7 PyCharm选择安装路径的界面

安装完成后的界面如图10-1-8所示。

图10-1-8 PyCharm安装成功界面

2.建立Python项目和文件

第一次启动PyCharm时,会显示若干初始化的提示信息,保持默认值即可。之后,进入创建项目的界面。如果不是第一次启动PyCharm,并且以前创建过Python项目,则会出现如图10-1-9所示的窗口。

图10-9 PyCharm创建项目界面

图10-1-9其右侧3个选项的含义分别是“创建新项目”、“打开已经存在的项目”和“从版本控制中检测项目”。选择“Create New Project”选项创建项目后,会出现选择项目存放路径界面,如图10-1-10所示。

图10-1-10 PyCharm项目存放路径界面

项目创建完成后,如果要在项目中创建Python文件,可选中项目名称,单击鼠标右键,在弹出的快捷菜单中选择“New”→“Python File”命令来新建文件,如图10-1-11所示。

图10-1-11 项目中创建Python

3.运行文件

在编辑窗口输入代码后,选择“Run”菜单中的“Run”命令可以运行程序。如图10-1-12所示为一个完整的程序,使用“Run”菜单中的命令可以调试和运行程序。

图10-1-12 PyCharm运行文件

10.2 Python语法

Python语法规范主要体现在程序语句的格式、代码块与缩进、注释等方面,而有一定复杂度的Python程序不可能只使用内置的函数或各种库,还需要引用很多外部第三方库或模块。

10.2.1 Python基础语法

1.标识符命名规则

文件名、类名、模块名、变量名、函数名等标识符可以由字母、数字和下划线组成,但第一个字符不能是数字。标识符区分大小写,没有长度限制。标识符不能使用计算机语言中预留的、有特殊作用的关键字。下面是Python中的合法标识符举例。

my_Var、Var3

下面是Python中的非法标识符举例。

2Var、vari#able、finally、stu@nu

2.代码的注释

Python的注释分为单行注释和多行注释两种。Python中单行注释以“#”开头,代码如下:

# 这是一个注释
print("Hello, World!")

多行注释用三个英文单引号“ ' ' ' ” 或者三个英文双引号“ """ ”将注释括起来,这种注释实际上是跨行的字符串,代码如下:

"""
这是多行注释,用三个双引号
这是多行注释,用三个双引号 
这是多行注释,用三个双引号
"""
print("Hello, World!")

3.代码的缩进

Python中的代码块是使用缩进来表示,缩进是指代码行前部预留若干空格,Python语法缩进的空格数在程序编辑环境中是可调整的,但要求同一个代码块的语句必须包含相同的缩进空格数。

4.代码分行书写

Python通常是一行书写一条语句,如果一行内编写多条语句,那么各语句间应使用分号分隔,建议每行只写一条语句,并且语句结束时不写分号。如果一条语句过长,可能需要换行书写,这时可以在语句的外部加上一对圆括号来实现,也可以使用“\”(反斜杠)来实现分行书写功能,与写在圆括号中的语句类似,写在“[]”、“{}”内的跨行语句被视为一行语句,而不再需要使用圆括号换行,代码如下:

#使用斜杠 \将一行的语句分行书写
total = item_one + \
    item_two + \
    item_three
#使用[]、 {} 或 () 括号分行书写
days = ['Monday', 'Tuesday', 'Wednesday',
    'Thursday', 'Friday']

5.Python关键字

关键字即保留字,用户不能将其用作任何标识符名称。Python的标准库提供了一个keyword模块,在IDLE中可以输出当前版本的所有关键字:

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

在Python中,用户需要注意True、False、None的大小写。如果用户需要查看关键字的信息,在IDLE中也可以使用help()命令进入帮助系统查看。

>>>help()    #进入Python的帮助系统
help>keywords  #查看关键字列表
he1p>except   #查看关键字“except”说明
help>quit    #退出帮助系统

6.算术运算符

算术运算可以完成数学中的加、减、乘、除四则运算。算术运算符包括“ + (加)”、“ - (减)”、“ * (乘)”、“ / (除)”、“ % (求余)”、“ ** (指数幂)”、“ ∥ (整除)”,算术运算符的代码如下:

>>>x1=17
>>>x2=4
>>>result1=x1+x2  #21
>>>result2=x1-x2  #13
>>>result3=x1*x2  #68
>>>result4=x1/x2  #4.25
>>>result5=x1%x2  #1
>>>result6=x1**x2#83521
>>>result7=x1//x2#4

由算术运算符将数值类型的变量连接起来就构成了算术表达式,它的计算结果是一个数值。不同类型的数据进行运算时,这些数据的类型应当是兼容的,并遵循运算符的优先级规则。

7.比较运算符

比较运算是指两个数据之间的比较运算。比较运算符主要有“ > (大于)”、“ < (小于)”、“ >= (大于等于)”、“ <= (小于等于)”、“ = =(双等于)”和“ != (不等于)”。比较运算符多用于数值型数据的比较,有时也用于字符串数据的比较,比较的结果是布尔值True或False。用比较运算符连接的表达式称为关系表达式,一般在程序分支结构中使用,比较运算符的代码如下:

>>>x='student'
>>>y="teacher"
>>>x>y 
False
>>>1en(x)==len(y)
True
>>>x!=y 
True
>>>x+y==y+x 
False

10.2.2 变量

变量用标识符来命名,变量名区分大小写。Python定义变量的格式类似“varName=value”,其中“varName”是变量名,“value”是变量的值,“=”被称为赋值运算符,即把“=”后面的值传递给前面的变量名。Python中的变量具有类型的概念,变量的类型由所赋的值来决定。在Python中,只要定义了一个变量,并且该变量存储了数据,那么变量的数据类型就已经确定了,系统会自动识别变量的数据类型。例如,若“x-8”,则“x”是整型数据;若“x="Hello"”,则“x”是一个字符串类型。变量也可以是列表、元组或对象等类型。如果希望查看变量的类型,可以使用函数type来实现。

10.2.3 数据类型

Python的数据类型主要有数值类型(Number)、字符串类型(Str)、列表(List)、元组(Tuple)、字典(Dictionary)和集合(Sets)等,而数值类型是Python的基本数据类型,包含整型(int)、浮点型(float)、复数类型(complex)和布尔类型(bool)4种,Python 3中不再有长整型(long)类型。

1.整数类型

整数类型简称整型,它与数学中整数的概念一致。整数类型的表示方式有十进制、二进制(以“0 B”或“0 b”开头)、八进制(以数字“0o”或“00”开头)和十六进制(以“0X”或“0x”开头)等。Python的整型数据理论上的取值范围是(-∞,∞),实际的取值范围受限于运行Python程序的计算机内存大小。下面都是一些合法的整数类型数据的举例。

100,-88,0o1234,0b1101,0xAAFF

Python有多种数据类型,并且有些数据类型的表现形式相同或相近,使用Python的内置函数type可以测试各种数据类型代码如下:

x=123
y=0b100
z=0xAB
print(x,y,z)
print(type(x),type(y),type(z)) #type函数测试数据类型

程序运行后,输出如下:

123 4 171
<class 'int'> <class 'int'> <class 'int'>

在上述代码中定义了3个变量,第1行代码中,变量x的值是一个十进制的整数;第2行代码中,变量y的值是一个二进制的整数;第3行代码中,变量z的值是一个十六进制的整数,它们都属于int类型。运行结果是输出了x、y、z这3个变量的十进制值,最后通过type函数显示了它们的数据类型。

2.浮点型

浮点数和整数在计算机内部存储的方式是不同的,整数运算永远是精确的,然而浮点数的运算则可能会有四舍五入的误差。浮点型可以用十进制或科学计数法表示。下面是用科学计数法表示的浮点型数据:

1.23e3,0.34E6,2.5E-3

其中E或e表示基数是10,后面的整数表示指数,指数的正负使用“+”和“-”号,其中正号“+”可以省略。需要注意的是,Python的浮点型占8个字节。

3.复数类型

Python支持复数,复数由实数部分和虚数部分构成,可以用“a+bj”,或者“complex(a,b)”表示,其中实数部分“a”和虚数部分“b”都是浮点型,虚数部分必须有后缀“j”或“J”,代码如下:

#复数类型测试
f1=1.2+3j
print(f1)
print(type(f1)) #使用type函数输出打印数据类型
print("f1的实数部分:"+str(f1.real))
print("f1的虚数部分:"+str(f1.imag))

程序运行后,输出如下:

(1.2+3j)
<class 'complex'>
f1的实数部分:1.2
f1的虚数部分:3.0

4.布尔类型

布尔类型数据只有两个取值真(True)和假(False)。如果将布尔值进行数值运算,真(True)会被当作整型1,假(False)会被当作整型0。每一个Python对象都自动具有布尔值,可用于布尔测试(如用在if结构或while结构中)。当在if语句中运行条件时,Python返回True或False。例如,根据条件是对还是错,打印一条消息,代码如下:

a = 200
b = 33
if b > a:
 print("b is greater than a")
else:
 print("b is not greater than a")

程序运行后,输出如下:

b is not greater than a

以下对象的布尔值都是False,包括None、False、整型0、浮点型0.0、复数0.0+0.0j、空字符串“ ”、空列表[]、空元组()、空字典{},这些数据的值可以用Python的内置函数bool来测试,代码如下:

a1=0
print("a1类型是:",end='')
print(type(a1),bool(a1))
a2=0.0
print("a2类型是:",end='')
print(type(a2),bool(a2))
a3='' #空字符串
print("a3类型是:",end='')
print(type(a3),bool(a3))
a4=[] #空列表
print("a4类型是:",end='')
print(type(a4),bool(a4))
a5={} #空字典
print("a5类型是:",end='')
print(type(a5),bool(a5))

程序运行后,输出如下:

a1类型是:<class 'int'> False
a2类型是:<class 'float'> False
a3类型是:<class 'str'> False
a4类型是:<class 'list'> False
a5类型是:<class 'dict'> False

5.字符串类型

Python的字符串是用单引号、双引号和三引号括起来的字符序列,用于描述信息。例如,"copyright"、"Python"、beatiful"、"beatiful"等,'hello'等同于"hello"。用户可以使用print函数显示字符串信息,由于字符串应用频繁,有时我们也将字符串当作基本的数据类型。用户也可以使用三个引号将多行字符串赋值给变量,代码如下:

a = """Python is a widely programming language. 
It was initially designed by Guido van Rossum in 1991 
and developed by Python Software Foundation. 
Its syntax allows programmers to express concepts in fewer lines of code."""

Python中的字符串是unicode字符的字节数组,Python没有字符数据类型,单个字符就是长度为1的字符串,方括号可用于访问字符串的元素。例如,获取位置1处的字符(请记住第一个字符的位置为0),代码如下:

a = "Hello, World!"
print(a[1])

运行程序后,输出为:

e

用户可以使用切片语法返回一定范围的字符,指定开始索引和结束索引,以冒号分隔,以返回字符串的一部分。例如,获取从位置2(包括)到位置5(不包括)的字符,代码如下:

a = "Hello, World!"
print(a[2:5])

运行程序后,输出为:

llo

用户也可以使用负索引从字符串末尾开始切片,(-1)是最后一个索引而(-2)是倒数第二个索引。例如,获取从倒数位置5(包括)到倒数位置2(不包括)的字符,从字符串末尾开始计数,代码如下:

b = "Hello, World!"
print(b[-5:-2])

运行程序后,输出为:

orl

用户需获取字符串的长度,可以使用len函数,代码如下:

a = "Hello, World!"
print(len(a))

运行程序后,输出为:

13

Python有一组可用于字符串的内置函数。例如,使用strip函数删除字符串开头和结尾的空白字符,代码如下:

a = " Hello, World! "
print(a.strip())

运行程序后,输出为:

Hello, World!

例如,使用lower函数返回小写的字符串,代码如下:

a = "Hello, World!"
print(a.lower())

运行程序后,输出为:

hello, world!

例如,使用upper函数返回大写的字符串,代码如下:

a = "Hello, World!"
print(a.upper())

运行程序后,输出为:

HELLO, WORLD!

例如,使用replace函数用另一段字符串来替换字符串,代码如下:

a = "Hello, World!"
print(a.replace("World", "Python"))

运行程序后,输出为:

Hello, Python!

例如,使用split函数根据分隔符来将原字符串拆分为子字符串,代码如下:

a = "Hello, World!"
print(a.split(",")) 

运行程序后,输出为:

['Hello', ' World!']

用户检查字符串中是否存在特定短语或字符,可以使用 in 或 not in 关键字。例如,检查以下文本中是否存在短语"ina",代码如下:

txt = "China is a great country"
x = "ina" in txt
print(x)

运行程序后,返回布尔数据,输出为:

True

如需串联或组合两个字符串,您可以使用“+”运算符。例如,将字符串a与一个空格及字符串b合并到字符串c中,代码如下:

a = "Hello"
b = "World"
c = a +" " + b
print(c)

运行程序后,输出为:

Hello World!

用户可以使用format函数组合字符串和数字,format函数接受传递的参数并格式化,然后将格式化结果放在占位符{}所在的字符串中。例如,使用format函数将数字插入字符串,代码如下:

age = 18
txt = "My name is Bill, and I am {}"
print(txt.format(age))

运行程序后,输出为:

My name is Bill, and I am 18

format函数接受不限数量的参数,并放在各自的占位符中,代码如下:

quantity = 3
itemno = 567
price = 25.8
myorder = "I want {} pieces of item {} for {} dollars."
print(myorder.format(quantity, itemno, price))

运行程序后,输出为:

I want 3 pieces of item 567 for 25.8 dollars.

也可以使用索引号{0}来确保参数被放在正确的占位符中,代码如下:

quantity = 3
itemno = 567
price = 25.3
myorder = "I want to pay {2} dollars for {0} pieces of item {1}."
print(myorder.format(quantity, itemno, price))

运行程序后,输出为:

I want to pay 25.3 dollars for 3 pieces of item 567.

用户要注意Python字符串上使用的内建函数,所有字符串函数都返回新值,而不会更改原始字符串。在需要使用特殊字符时,Python用反斜杠(\)转义字符,具体见表10-1。

表10-1 转义字符

6.列表类型(List)

Python有6个序列的内置类型,最常见的是列表和元组,序列都可以进行的操作包括索引、切片、加、乘及检查成员。要注意的是Python没有内置对数组的支持,但可以使用列表代替。列表是一种数据集合,是Python中最基本的数据结构。列表使用方括号,元素之间用英文逗号分隔,列表中的数据项不需要具有相同的类型。列表中的每个元素都分配一个数字来表示它的位置,也就是索引,第一个索引是0,第二个索引是1,依此类推。此外,Python已经内置确定序列的长度以及确定最大和最小的元素的函数。创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可,与字符串的索引一样,列表索引从0开始,并可以进行截取、切片或组合等,通过索引来截取列表中的元素代码如下:

list1 = ['Google', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7];
print ("list1[0]为:", list1[0])
print ("list2[1:5]为:", list2[1:5])

运行程序后,输出为:

list1[0]为:Google
list2[1:5]为:[2, 3, 4, 5]

用户如需更改列表某个元素的值,需要引用索引号,代码如下:

thislist = ["apple", "banana", "cherry"]
thislist[1] = "mango"
print(thislist)

运行程序后,输出为:

['apple', 'mango', 'cherry']

有一个列表变量L其中有三个元素,其可以表示为L1,2,3,利用切片操作列表指定参数Lstart:end :step,其中“step”表示步长,代表每“step”个取一个,其中Python切片的用法如下:

L[0:3]#从索引0开始取,直到索引3为止,不包括索引3,即索引0,1,2
L[:]#表示从头到尾
L[-2:-1]#表示从倒数第二个元素取到最后一个元素,即输出倒数第二个元素,不包括最后一个元素
L[-3:]#表示从倒数第三个元素取到尾
L[-1:-3:-1]#表示从倒数第一个数按-1取,取至倒数第三个为止,即输出最后两个元素
L[3::3]#表示从索引3开始每3个数里取一个,取至最后一个元素为止
注:最后一个元素为-1。

range函数可创建一个整数列表,这个函数的使用为range(start,stop,step),其中start表示计数从start开始,默认是从0开始,如range(5)等价于range(0,5),stop表示计数到stop结束,但不包括stop,如range(0,5)表示0,1,2,3,4没有5,step表示步长可以省略,默认为1,如range(0,5)等价于range(0,5,1),range函数创建列表的代码如下:

>>>range(10)    # 从0开始到 10(不包括)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)   # 从 1 开始到 11(不包括)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5) # 步长为 5
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3) # 步长为 3
[0, 3, 6, 9]
>>> range(0, -10, -1) # 负数
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

用户要确定列表中有多少项元素,可以使用len函数,代码如下:

thislist = ["apple", "banana", "cherry"]
print(len(thislist))

运行程序后,输出为:

3

用户要将元素添加到列表的末尾,可以使用append函数,代码如下:

thislist = ["apple", "banana", "cherry"]
thislist.append("orange")
print(thislist)

运行程序后,输出为:

['apple', 'banana', 'cherry', 'orange']

用户要在指定的索引处添加元素,可以使用insert函数,代码如下:

thislist = ["apple", "banana", "cherry"]
thislist.insert(1, "orange")
print(thislist)

运行程序后,输出为:

['apple', 'orange', 'banana', 'cherry']

用户可以使用remove函数删除指定的元素,代码如下:

thislist = ["apple", "banana", "cherry"]
thislist.remove("banana") #remove函数删除指定的元素
print(thislist)

运行程序后,输出为:

['apple', 'cherry']

Python有几种方法可以连接或串联两个或多个列表,最简单的方法之一是使用“+”运算符,代码如下:

list1 = ["a", "b" , "c"]
list2 = [1, 2, 3]
list3 = list1 + list2
print(list3)

运行程序后,输出为:

['a', 'b', 'c', 1, 2, 3]

连接两个列表的另一种方法是将list2中的所有项一个接一个地追加到list1中,代码如下:

list1 = ["a", "b" , "c"]
list2 = [1, 2, 3]
for x in list2:
 list1.append(x)
print(list1)

运行程序后,输出为:

['a', 'b', 'c', 1, 2, 3]

也可以使用extend函数,其目的是将一个列表中的元素添加到另一列表中,代码如下:

list1 = ["a", "b" , "c"]

list2 = [1, 2, 3]

list1.extend(list2)

print(list1)

运行程序后,输出为:

['a', 'b', 'c', 1, 2, 3]

用户也可以使用list构造函数创建一个新列表,代码如下:

thislist = list(("apple", "banana", "cherry")) # 请注意双括号
print(thislist)

运行程序后,输出为:

['apple', 'banana', 'cherry']

Python可以在列表上使用的内建函数有多种,具体见表10-2。

表10-2 列表内建函数

7.元组类型(Tuple)

元组是由0个或多个元素组成的不可变序列类型。元组与列表的区别在于元组的元素不能修改。创建元组时,只要将元组的元素用小括号括起来,并使用逗号隔开即可。如(‘physics',chemistry',1997,2000)就是一个元组。

与列表类似,用户也可以通过引用方括号内的索引号来访问元组中的元素,代码如下:

thistuple = ("apple", "banana", "cherry")
print(thistuple[1])

运行程序后,输出为:

banana

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,代码如下:

tup1 = (12, 34.56);
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2;
print (tup3)

运行程序后,输出为:

(12, 34.56, 'abc', 'xyz')

虽然元组是不可变的,或者也称为恒定的,但是用户也可以将元组转换为列表,更改列表,然后将列表转换回元组,代码如下:

x = ("apple", "banana", "cherry")
y = list(x)
y[1] = "kiwi"
x = tuple(y)
print(x)

运行程序后,输出为:

('apple', 'kiwi', 'cherry')

元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,代码如下:

tup = ('Google', 'Tencent', 1997, 2000)
print (tup)
del tup;
print ("删除后的元组 tup : ")
print (tup)

以上实例元组被删除后,输出变量会有异常信息。

元组一旦创建,您就无法向其添加项目,元组是不可改变的,用户无法向元组添加项目,代码如下:

thistuple = ("apple", "banana", "cherry")
thistuple[3] = "orange" # 会引发错误
print(thistuple)

运行程序后,输出为:

File "demo_tuple_add.py", line 2, in <module>
 thistuple[3] = "orange" # This will raise an error
 TypeError: 'tuple' object does not support item assignment

如果用户创建只包含一个元素的元组,就必须在该元素后添加一个逗号,否则Python无法将变量识别为元组,代码如下:

thistuple = ("apple",)
print(type(thistuple))
#不是元组
thistuple = ("apple")
print(type(thistuple))

运行程序后,输出为:

<class 'tuple'>
<class 'str'>

用户要确定元组有多少项,可以使用len函数,代码如下:

thistuple = ("apple", "banana", "cherry")
print(len(thistuple))

运行程序后,输出为:

3

用户要连接两个或多个元组,可以使用“+”运算符,代码如下:

tuple1 = ("a", "b" , "c")
tuple2 = (1, 2, 3)
tuple3 = tuple1 + tuple2
print(tuple3)

运行程序后,输出为:

('a', 'b', 'c', 1, 2, 3)

用户可以使用tuple构造函数来创建元组,代码如下:

thistuple = tuple(("apple", "banana", "cherry")) # 请注意双括号
print(thistuple)

运行程序后,输出为:

('apple', 'banana', 'cherry')

Python可以在元组上使用的内建函数见表10-3。

表10-3 元组内建函数

8.集合类型(Set)

在Python中,集合是一组对象的集合,对象可以是各种类型。集合由各种类型的元素组成,集合是无序和无索引的集合,元素之间没有任何顺序,并且元素都不重复。集合用大括号“{ }”编写,一旦集合创建就无法更改项目,但是可以添加新项目。创建一个空集合必须用set函数而不是“{ }”,因为“{ }”是用来创建一个空字典。

集合是无序的,因此无法确定项目的显示顺序,代码如下:

thisset = {"apple", "banana", "cherry"}
print(thisset)

运行程序后,输出为:

{'banana', 'apple', 'cherry'}

用户无法通过引用索引来访问集合中的元素,因为集合是无序的没有索引但,是可以使用for循环遍历集合,或者使用in关键字查询集合中是否存在指定值,代码如下:

thisset = {"apple", "banana", "cherry"}
for x in thisset:
 print(x)

运行程序后,输出为:

cherry
banana
apple
检查集合中是否存在字符串“banana”:
thisset = {"apple", "banana", "cherry"}
print("banana" in thisset)

运行程序后,输出为:

True

集合中的元素都不重复,当有重复元素时也能去重,代码如下:

basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} 
print(basket) # 集合去重

运行程序后,输出为:

{'orange', 'banana', 'pear', 'apple'}

要将一个新元素添加到集合,可以使用add函数,代码如下:

thisset = {"apple", "banana", "cherry"}
thisset.add("orange")
print(thisset)

运行程序后,输出为:

{'orange', 'cherry', 'apple', 'banana'}

使用update函数将多个新元素添加到集合中,并且参数可以是列表、元组、字典等,多个新元素用逗号分开,代码如下:

thisset = {"apple", "banana", "cherry"}
thisset.update(["orange", "mango", "grapes"])
print(thisset)

运行程序后,输出为:

{'cherry', 'orange', 'banana', 'apple', 'mango', 'grapes'}

用户可以使用union函数连接两个或多个集合,结果将返回包含两个集合中所有项目的新集合,代码如下:

set1 = {"a", "b" , "c"}
set2 = {1, 2, 3}
set3 = set1.union(set2)
print(set3)

运行程序后,输出为:

{'b', 1, 'a', 2, 'c', 3}

将元素从集合中移除,可以使用remove函数,如果元素不存在,则会发生错误,代码如下:

thisset = set(("Google", "Tencent", "Taobao"))
thisset.remove("Taobao")
print(thisset)
thisset.remove("Facebook")

运行程序后,输出为:

{'Google', Tencent} 
Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'Facebook'

此外还有一个方法也可以移除集合中的元素,使用discard函数,同样的如果元素不存在,不会发生错误,代码如下:

thisset = set(("Google", "Tencent", "Taobao")) 
thisset.discard("Facebook") # 不存在不会发生错误 
print(thisset) 

运行程序后,输出为:

{'Taobao', 'Google', 'Tencent'}

Python可以在集合上使用的内建函数具体见表10-4。

表10-4 集合内建函数

要注意的是s.update(“string”)与s.update({“string”})含义不同,s.update(“string”)将字符串拆分为单个字符后,再一个一个添加到集合中,有重复的会忽略,s.update({“string”})将字符串添加到集合中,有重复的会忽略。

9.字典类型(Dictionary)

字典是Python中唯一内置的映射类型,可用来实现通过数据查找关联数据的功能。字典是一个无序、可变和有索引的集合,字典中的每一个元素都包含两部分:键(key)和值(value),字典用大括号“{ }”来表示,每个元素的键和值用冒号分隔,元素之间用逗号分隔。由于字典中的键是非常关键的数据,而程序需要通过键来访问值,因此字典中的键不允许重复,代码如下:

dict = {'Name': '腾讯大学', 'Age': 7, 'Class': 'First'}
print ("dict['Name']: ", dict['Name'])print ("dict['Age']: ", dict['Age'])

运行程序后,输出为:

dict['Name']: 腾讯大学
dict['Age']: 7

如果用字典里没有的键访问数据,会输出错误,代码如下:

dict = {'Name': '腾讯大学', 'Age': 7, 'Class': 'First'};
print ("dict['Alice']: ", dict['Alice'])

运行程序后,输出为:

Traceback (most recent call last):
 File "test.py", line 5, in <module>
 print ("dict['Alice']: ", dict['Alice'])
KeyError: 'Alice'

字典中修改已有键/值对和添加键/值对的代码如下:

dict = {'Name': 'Tony', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8;        # 修改键Age的值
dict['School'] = "腾讯大学" # 添加信息
print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

运行程序后,输出为:

dict['Age']: 8
dict['School']: 腾讯大学

删除字典元素,能删单一的元素也能清空字典,清空只需一项操作。显示删除一个字典用del命令,代码如下:

dict = {'Name': 'Tony', 'Age': 7, 'Class': 'First'}
del dict['Name'] # 删除键 'Name'
dict.clear()   # 删除字典del dict     # 删除字典
print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

但这会引发一个异常,因为用执行 del 操作后字典不再存在,运行程序后,输出为:

Traceback (most recent call last):
 File "test.py", line 9, in <module>
 print ("dict['Age']: ", dict['Age'])
TypeError: 'type' object is not subscriptable

字典值可以没有限制地取任何Python对象,既可以是标准的对象,也可以是用户定义的,但键不行。需要记住不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,代码如下:

dict = {'Name': '小红', 'Age': 7, 'Name': '小明'}
print ("dict['Name']: ", dict['Name'])

运行程序后,输出为:

dict['Name']: 小明

Python可以在字典上使用的内建函数具体见表10-5。

表10-5 字典内建函数

10.2.4流程控制

在进行程序设计的时候,会经常进行逻辑判断,根据不同的结果做不同的事,或者重复做某件事,对类似这样的工作称为流程控制,Python常见的流程控制主要有如下几种。

1.条件语句(if语句)

条件语句是通过判断一条或多条语句的状态(True或者False)来决定执行的代码块,Python中if语句的一般形式如下所示:

if condition_1:

  statement_block_1

elif condition_2:

  statement_block_2

else:

  statement_block_3

如果condition_1为True将执行statement_block_1块语句,如果condition_1为False,将判断condition_2,如果condition_2为True将执行statement_block_2块语句,如果condition_2为False,将执行statement_block_3块语句。Python中用elif代替了elseif,所以if语句的关键字为“if–elif–else”。

注意:

每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块。

使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。

在Python中没有switch–case语句。

2.for循环语句

Python中for循环可以用于迭代序列(即列表、元组、字典、集合或字符串),这是与其他编程语言中的for循环不太相似的地方,更像其他面向对象编程语言中的迭代器方法。通过使用for循环,可以为列表、元组、集合中的每个项目执行一组语句。

输出列表中的每个元素,代码如下:

fruits = ["apple", "banana", "cherry"]
for x in fruits:
print(x)

运行程序后,输出为:

apple
banana
cherry

字符串也是可迭代的对象,可以使用for语句进行遍历,代码如下:

for x in "腾讯":
print(x)

运行程序后,输出为:

腾
讯

3.while循环语句

Python的while循环语句和C语言几乎一样,只是判断条件没有括号围着。例如,计算Fibonacci数列,代码如下:

a, b = 0, 1
fib = []
while len(fib) < 10:  #循环条件没有括号
  a, b = b, a+b
  fib.append(b)
print(fib)

运行程序后,输出为:

[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

10.2.5函数

Python提供了许多内建函数,如print函数等。除此以外,用户也可以自定义函数。自定义函数的规则如下:

自定义函数以def关键词开头,后接函数标识符名称和圆括号。

参数和自变量必须放在圆括号中间。

函数的第一行语句可以选择性地使用文档字符串——用于存放函数说明。

函数内容以冒号起始,并且缩进。

return 表达式结束函数,选择性地返回一个值给调用方,不带表达式的return相当于返回None。

自定义函数的一般格式如下:

def 函数名(参数列表):
  函数体

如需调用函数,要使用函数名称并加上括号,代码如下:

def welcome(name):
  print("你好", name)
welcome("小明")

运行程序后,输出为:

你好 小明

如果不知道传递给自定义函数多少个参数,要在函数定义的参数名称前添加星号“*”。自定义函数将接收一个参数元组,并相应地访问参数元组中的元素,代码如下:

def my_function(*kids):
 print("年龄最小的孩子是:" + kids[1])
my_function("小明", "小红", "小天")

运行程序后,输出为:

年龄最小的孩子是:小红

10.2.6面向对象

面向对象的一些基本特征,主要有:

类—用来描述具有相同的属性和方法的对象的集合。它定义了该类中每个对象所共有的属性和方法,对象是类的实例,如Dog类。

公有变量—类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

数据成员—类变量或者实例变量用于处理类及其实例对象的相关的数据。

方法重写—如果从父类继承的方法不能满足子类的需求,可以对其进行改写,称为方法的重写。

私有变量—只能在本类中被访问。

实例变量—在类的声明中,属性是用变量来表示的,这种变量就是实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。

继承—即一个子类继承父类的属性和方法。继承也允许把一个子类的对象作为一个父类对象对待,如Dog类继承自Animal类。

实例化—创建一个类的实例,类的具体对象。

方法—类中定义的函数。

对象—通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

Python提供了面向对象编程的所有基本功能,例如类的继承机制允许多个父类,子类可以覆盖父类中的任何方法,方法中可以调用父类中的同名方法,对象可以包含任意数量和类型的数据。

1.类

语法格式如下:

class ClassName:
  <statement-1>
  <statement-N>

用户创建一个类之后,可以通过类名访问其属性。类对象支持两种操作属性引用和实例化。属性引用使用的标准语法为obj.name。类的代码如下:

class MyClass:
  """一个简单的类实例"""
  i = 12345
  def func(self):
    return 'hello world'
# 实例化类
x = MyClass()
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 func 输出为:", x.func())

以上代码创建了一个新的类MyClass,x为该类实例化对象。运行程序后,输出结果为:

MyClass 类的属性 i 为: 12345
MyClass 类的方法 func 输出为: hello world

在Python中,面向对象编程有以下几种方式来定义变量:

xx—公有变量。

_xx—单前置下划线,私有属性或方法,类对象和子类可以访问,from somemodule import *禁止导入。

__xx—双前置下划线,私有化属性或方法,无法在外部直接访问。

xx—双前后下划线,系统定义名字,建议用户不要自己定义这样的名字。

xx_—单后置下划线,用于避免与Python关键词的冲突。

2.构造方法

很多类都倾向于将对象创建为有初始状态的,类可以定义一个名为init( )的特殊方法(构造方法),init( )方法可以有参数,参数通过 init( )传递到类的实例化操作上,代码如下:

class Complex:
   def __init__(self, realpart, imagpart):
     self.r = realpart
     self.i = imagpart
x = Complex(3.0, -4.5)
print("实数部分是:"+str(x.r)+"虚数部分是:"+str(x.i))

运行程序后,输出结果为:

实数部分是:3.0虚数部分是:-4.5

3.类的方法

在类的内部,可以使用def关键字为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数,代码如下:

class people:
  #定义基本属性
  name = ''
  age = 0
  #双下划线定义私有属性,私有属性在类外部无法直接进行访问
  __weight = 0
  #双前后下划线定义构造方法
  def __init__(self,n,a,w):
    self.name = n
    self.age = a
    self.__weight = w
  def speak(self):
    print("%s 说: 我 %d 岁。" %(self.name,self.age))
# 实例化类
p = people('Tony',10,30)
p.speak()

执行以上程序输出结果为:

Tony 说: 我 10 岁。

4.继承

Python支持类的继承,如果一种语言不支持继承,类就没有什么意义。子类的定义格式如下所示:

class DerivedClassName(BaseClassName1):
  <statement-1>
  <statement-N>

继承的代码如下:

class people:
  #定义基本属性
  name = ''
  age = 0
  #定义私有属性,私有属性在类外部无法直接进行访问
  __weight = 0
  #定义构造方法
  def __init__(self,n,a,w):
    self.name = n
    self.age = a
    self.__weight = w
  def speak(self):
    print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
  grade = ''
  def __init__(self,n,a,w,g):
    #调用父类的构函
    people.__init__(self,n,a,w)
    self.grade = g
  #覆写父类的方法
  def speak(self):
    print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
s = student('ken',10,60,3)
s.speak()

执行以上程序输出结果为:

ken 说: 我 10 岁了,我在读 3 年级

父类必须与子类定义在一个作用域内。父类定义在另一个模块中,可以使用如下格式:

class DerivedClassName(modname.BaseClassName):

5.多继承

Python多继承的类定义形如下例:

class DerivedClassName(Base1, Base2, Base3):
  <statement-1>
  <statement-N>

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,Python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。

class people:
  #定义基本属性
  name = ''
  age = 0
  #定义私有属性,私有属性在类外部无法直接进行访问
  __weight = 0
  #定义构造方法
  def __init__(self,n,a,w):
    self.name = n
    self.age = a
    self.__weight = w
  def speak(self):
    print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
  grade = ''
  def __init__(self,n,a,w,g):
    #调用父类的构函
    people.__init__(self,n,a,w)
    self.grade = g
  #覆写父类的方法
  def speak(self):
    print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
#另一个类,多重继承之前的准备
class boyStudent():
  topic = ''
  name = ''
  def __init__(self,n,t):
    self.name = n
    self.topic = t
  def speak(self):
    print("我叫 %s,我是一个男生,我演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(boyStudent, student):
  a =''
  def __init__(self,n,a,w,g,t):
    student.__init__(self,n,a,w,g)
    boyStudent.__init__(self, n, t)
test = sample("Tim",25,80,4,"Python")
test.speak()  #方法名同,默认调用的是在括号中排前地父类的方法

执行以上程序输出结果为:

我叫 Tim,我是一个男生,我演讲的主题是 Python

6.方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:

class Parent:    # 定义父类
  def myMethod(self):
   print ('调用父类方法')
class Child(Parent): # 定义子类
  def myMethod(self):
   print ('调用子类方法')
c = Child()     # 子类实例
c.myMethod()     # 子类调用重写方法

执行以上程序输出结果为:

调用子类方法

10.3 Python经典库的使用

Python标准库非常庞大,所提供的组件涉及范围十分广泛,用户可以依靠它们来实现系统级功能,如文件I/O等,此外还有大量以Python编写的模块,提供了编程中许多问题的标准解决方案。

10.3.1 模块

在计算机程序的开发过程中,一个文件里代码会越来越长,越来越不容易维护。为了编写可维护的代码,可以把很多函数分组,分别放到不同的文件里,很多编程语言都采用这种方式,在Python中,一个.py文件就称之为一个模块(Modules)。模块可以被别的程序引入,以使用该模块中的函数等功能,使用模块也可以避免函数名和变量名冲突。创建模块只需将代码保存在文件扩展名为.py的文件中。如创建名为mymodule.py的文件,代码如下:

def greeting(name):
 print("Hello, " + name)

可以用import语句来使用刚刚创建的模块,导入名为mymodule的模块,并调用greeting函数,如果使用模块中的函数时,使用以下语法module_name.function_name,代码如下:

import mymodule
mymodule.greeting("Bill")

以上代码执行结果如下所示:

Hello, Bill

模块可以包含已经描述的函数,也可以包含各种类型的变量(数组、字典、对象等),创建名为mymodule.py的文件,代码如下:

person1 = {
 "name": "Bill",
 "age": 18,
 "country": "China"
}

导入名为mymodule的模块,并访问模块mymodule.py中的字典变量person1,代码如下:

import mymodule
a = mymodule.person1["country"]
print(a)

以上代码执行结果如下所示:

China

用户也可以在导入模块时使用as关键字给相应的模块创建别名,以下代码是为mymodule创建别名mx,然后访问模块中的字典变量person1:

import mymodule as mx
a = mx.person1["age"]
print(a)

以上代码执行结果如下所示:

18

用户也可以使用from关键字选择仅从模块导入部分部件,例如名为mymodule的模块拥有一个方法和一个字典变量,代码如下:

def greeting(name):
 print("Hello, " + name)
person1 = {
 "name": "Bill",
 "age": 18,
 "country": "China"
}

如果仅从模块导入字典变量person1,在使用from关键字导入时,请勿在引用模块中的元素时使用模块名称,应使用person1"age",而不是mymodule.person1"age",代码如下 :

from mymodule import person1
print(person1["age"])

以上代码执行结果如下所示:

18

10.3.2 NumPy库的使用

NumPy是Python语言的一个数值数学扩展库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

1.NumPy库的安装

安装NumPy库最简单的方法就是通过调用cmd命令提示符然后使用pip工具,由于国内使用pip原始安装源可能存在下载速度缓慢或安装失败等问题,用户可以使用清华镜像源地址“https://pypi.tuna.tsinghua.edu.cn/simple”,安装代码如下:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy

测试NumPy是否安装成功,可以在IDLE中输入以下代码:

>>> from numpy import *
>>> eye(3)
array([[1., 0., 0.],
    [0., 1., 0.],
    [0., 0., 1.]])

代码中from numpy import * 为导入numpy库,eye(3)为生成对角矩阵。

2.ndarray数组对象

NumPy的主要对象是ndarray数组对象,如图10-13所示。它是一个元素表(通常是数字),所有类型都相同,由非负整数元组索引。与Python中的其他容器对象一样,可以通过对数组进行索引或切片,以及通过ndarray的方法和属性来访问和修改ndarray的内容。

图10-3-1 ndarray数组对象

ndarray数组对象维度(dimension)也称为轴(axis),如在二维平面世界中,描述一个点的时候,通常使用x轴、y轴,这样就能确定一个点的具体位置了。如果是立体的三维世界中,就会多出一个z轴。秩(rank)是指轴的数量,或者维度的数量,是一个标量。numpy.array与标准Python库类array.array不同,后者只处理一维数组并提供较少的功能。

ndarray数组常用的属性是:

ndarray.ndim—数组的轴(维度)的个数,维度的数量被称为秩。

ndarray.shape—数组的形状。这是一个整数的元组,表示每个维度中数组的大小。对于有n行和m列的矩阵,形状(shape)将是(n,m)。

ndarray.size—数组元素的总数,等于形状(shape)中元素个数的乘积。

ndarray.dtype—一个描述数组中元素类型的对象。NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64。

ndarray.itemsize—数组中每个元素的字节大小。例如,元素为float64类型的数组的itemsize为8(=64/8),而complex32类型的数组的itemsize为4(=32/8)。它等于ndarray.dtype.itemsize。

ndarray.data—该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。

ndarray对象的属性的代码如下:

>>> import numpy as np
#arange(n):生成从0到n的序列;reshape(x,y):将序列重新塑造成3行5列的narray
>>> a = np.arange(15).reshape(3, 5) 
>>> a
array([[ 0, 1, 2, 3, 4],
    [ 5, 6, 7, 8, 9],
    [10, 11, 12, 13, 14]])
>>> a.shape #返回narray的(行数,列数)
(3, 5)
>>> a.ndim #返回narray的秩
2
>>> a.dtype.name #返回narray中数据的类型
'int64'
>>> a.itemsize #返回narray中每个元素的字节数大小8 = 64 / 8
8
>>> a.size #返回narray中的元素个数
15
>>> type(a) #返回a的类型
<type 'numpy.ndarray'>

3.矩阵乘法

与许多矩阵语言不同,乘积运算符“*”在NumPy数组中按元素进行乘运算,而矩阵乘积可以使用“@”运算符或dot函数执行,代码如下:

import numpy as np
A = np.array( [[1,1],
    [0,1]] )
B = np.array( [[2,0],
     [3,4]] )
print("元素乘:")
print(A * B)           # 元素乘
print("矩阵乘法1:")
print(A @ B)            # 矩阵乘法1
print("矩阵乘法2:")
print(np.dot(A,B))          # 矩阵乘法2

运行程序后,输出为:

元素乘:
[[2 0]
 [0 4]]
矩阵乘法1:
[[5 4]
 [3 4]]
矩阵乘法2:
[[5 4]
 [3 4]]

10.3.3 Matplotlib库的使用

Matplotlib是Python的绘图库,可与NumPy一起使用,也可以和图形工具包一起使用,如PyQt和wxPython。

1.Matplotlib库的安装

安装Matplotlib最简单的方法就是通过调用cmd命令提示符然后使用pip工具,用户可以使用清华镜像源地址“https://pypi.tuna.tsinghua.edu.cn/simple”,安装代码如下:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib

安装完后,可以使用下面的命令来查看是否安装了Matplotlib模块。

pip list

2.Matplotlib的基本用法

Matplotlib的默认配置都允许用户自定义。用户可以调整大多数的默认配置:图片大小和分辨率(dpi)、线宽、颜色、风格、坐标轴、坐标轴以及网格的属性、文字与字体属性等。Matplotlib的默认配置在大多数情况下已经做得足够好,只在很少的情况下才会更改这些默认配置。

用默认配置在同一张图上绘制正弦和余弦函数图像,代码如下:

import numpy as np
import matplotlib.pyplot as plt
#生成从−π 到+π等间隔的256个值的数组
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C = np.cos(X)   #余弦函数
S = np.sin(X)   #正弦函数
plt.plot(X,C,'y:')
plt.plot(X,S,'r--')
plt.show()

X是一个利用linspace生成的数组,包含了从−π到+π等间隔的256个值。C和S则分别是这256个值对应的余弦和正弦函数值组成的数组。plt.plot(X,C,'y:')为绘制X横坐标,C纵坐标的图像,增加了一个字符串'y:'参数,其中y表示黄色,:表示点线,r表示红色,--表示虚线,代码输出如图10-3-2所示。

图10-3-2 绘制正弦和余弦函数图像

常见各种线的样式表示参数,见表10-6。

表10-6 线的样式表示参数

3.多张子图绘制

多张子图绘制需要在调用plot函数之前先调用subplot函数。subplot函数的第一个参数代表子图的总行数,第二个参数代表子图的总列数,第三个参数代表活跃区域,代码如下:

import numpy as np
import matplotlib.pyplot as plt
ax1 = plt.subplot(2, 2, 1) # (行,列,活跃区)
 plt.plot(x, np.sin(x), 'r')
 ax2 = plt.subplot(2, 2, 2, sharey=ax1) # 与 ax1 共享y轴
 plt.plot(x, 2 * np.sin(x), 'g')
 ax3 = plt.subplot(2, 2, 3)
 plt.plot(x, np.cos(x), 'b')
 ax4 = plt.subplot(2, 2, 4, sharey=ax3) # 与 ax3 共享y轴
 plt.plot(x, 2 * np.cos(x), 'y')
 plt.show()

运行程序后,输出如图10-3-3所示。

图10-3-3 多张子图绘制

10.3.4 Pandas库的使用

Pandas是一个基于NumPy的数据分析工具,其中纳入了大量标准的数据模型,并通过管理索引来快速访问数据、执行分析和转换运算,并提供了高效地操作大型数据集所需的工具。Pandas适合于许多不同类型的数据,包括:

具有异构类型列的表格数据,例如SQL表格或Excel数据。

有序和无序(不一定是固定频率)时间序列数据。

具有行列标签的任意矩阵数据(均匀类型或不同类型)。

任何其他形式的观测/统计数据集。

1.Pandas库的安装

安装Pandas最简单的方法就是通过调用cmd命令提示符然后使用pip工具,用户可以使用清华镜像源地址“https://pypi.tuna.tsinghua.edu.cn/simple”,安装代码如下:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas

安装完后,可以使用下面的命令来查看是否安装了Pandas模块。

pip list

2.Pandas数据结构

Pandas的数据结构主要如下:

Series一维数据带有标签的同构类型数组。

DataFrame二维数据表格结构,带有标签,大小可变,且可以包含异构的数据列,可以看做是Series的容器,一个DataFrame中可以包含若干个Series。

Series是一维结构的数据,可以直接通过列表来创建,代码如下:

import pandas as pd
 series1 = pd.Series([1, 2, 3, 4])
 print("series1.values: {}\n".format(series1.values))
 print("series1.index: {}\n".format(series1.index))

运行程序后,数据在第一行输出,数据的索引在第二行输出,具体如下:

series1.values: [1 2 3 4]
series1.index: RangeIndex(start=0, stop=4, step=1)
DataFrame是二维数据表格结构,可以通过NumPy的接口来创建,代码如下:
import pandas as pd
import numpy as np
df1 = pd.DataFrame(np.arange(12).reshape(4,3))
print("df1:\n{}\n".format(df1.values))

运行程序后,输出如下:

df1:
[[ 0 1 2]
 [ 3 4 5]
 [ 6 7 8]
 [ 9 10 11]]

项目实施

对于Python工程师或运维工程师来说,一定会遇到需要编写Python程序来管理云资源的应用场景,如查看CVM的实例列表等信息、查看VPC列表等信息、查看子网列表等信息。通过Python调用云API管理云资源是Python工程师或运维工程师必备的知识和技能。

需要完成的任务:

安装Python的云SDK。

查看CVM实例列表。

查看CVM实例机型列表。

查看VPC列表。

查看VPC下的云主机实例列表。

查看子网列表。

10.4 Python调用云API管理云资源

腾讯官方的Python SDK是云API平台的配套工具,目前已经支持CVM、VPC、CBS等产品,用户可以登录腾讯云控制台,在访问管理控制台的“API密钥管理”页面获取SecretID和SecretKey,SecretID用于标识API调用者的身份,SecretKey用于加密签名字符串和服务器端验证签名字符串的密钥,SecretKey需妥善保管,避免泄露。获取调用地址(endpoint)一般格式为*.tencentcloudapi.com,例如CVM的调用地址为cvm.tencentcloudapi.com,具体地址可以参考各云产品的说明。

10.4.1 安装云SDK

用户使用了云服务后,不仅仅只在控制台对服务进行调用,而是要扩展到各种平台,这就需要通过API接口进行调用。有时候,云服务提供商为用户提供了适合于对应平台的SDK(API集合),可以很方便的实现对云服务的调用。安装腾讯云SDK最简单的方法就是通过调用cmd命令行,然后使用pip工具,安装代码如下:

pip install tencentcloud-sdk-python

安装完后,可以使用下面的命令来查看是否安装了腾讯云SDK。

pip list

用户可以到网址“https://cloud.tencent.com/document/sdk/”中,获取更详细的腾讯云SDK文档。

10.4.2 查看CVM实例列表

DescribeInstances接口是用于查询一个或多个实例的详细信息的。接口请求域名为cvm.tencentcloudapi.com。可以根据实例ID、实例名称或者实例计费模式等信息来查询实例的详细信息。过滤信息详细请见过滤器Filter。如果参数为空,返回当前用户一定数量(默认为20)的实例。支持查询实例的最新操作以及最新操作状态。具体代码如下:

# 查看 CVM 实例列表 DescribeInstances  
import json
 from tencentcloud.common import credential
 from tencentcloud.common.profile.client_profile import ClientProfile
 from tencentcloud.common.profile.http_profile import HttpProfile
 from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
 from tencentcloud.cvm.v20170312 import cvm_client, models
 try:
   # 腾讯云教育沙箱验证上机的密钥
  const secretId = "yourSecretId"   # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  const secretKey = "yourSecretKey" # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  #身份令牌配置
  cred = credential.Credential(secretId, secretKey)
  #http配置
  httpProfile = HttpProfile()
  httpProfile.endpoint = "vpc.tencentcloudapi.com"
  #客户端配置
  clientProfile = ClientProfile()
   clientProfile.httpProfile = httpProfile
   # 地区选择是跟学校地域相关,腾讯沙箱云地区是广州
   client = cvm_client.CvmClient(cred, "ap-guangzhou", clientProfile)
   req = models.DescribeInstancesRequest()
   params = '{}'
   req.from_json_string(params)
   resp = client.DescribeInstances(req)
   # 输出 JSON 格式的字符串回包
   dic = json.loads(resp.to_json_string())
   # 格式化输出json字符串 ensure_ascii False输出中文,4个缩进
   js = json.dumps(dic, ensure_ascii=False, indent=4)
   print(js)
 except TencentCloudSDKException as err:
   print(err)

程序运行结果跟实际腾讯云沙箱中的CVM实例有关,类似的输出如下:

{
  "TotalCount": 0,
  "InstanceSet": [],
  "RequestId": "37a1f571-a3d5-46e0-b1e2-7e2429b4ff58"
}

10.4.3 查看CVM实例机型列表

DescribeInstanceTypeConfigs接口是用于查询实例机型配置的,接口请求域名cvm.tencentcloudapi.com。可以根据zone、instance-family来查询实例机型配置。过滤条件详见过滤器Filter。如果参数为空,返回指定地域的所有实例机型配置。该接口可以查看可购买机型信息,用户可与自己的机器进行对比。具体代码如下:

# 查看 CVM 实例机型列表 DescribeInstanceTypeConfigs
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.cvm.v20170312 import cvm_client, models
try:
# 腾讯云教育沙箱验证上机的密钥
  const secretId = "yourSecretId"   # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  const secretId = "yourSecretId"   # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  cred = credential.Credential(secretId, secretKey)
  #身份令牌配置
  cred = credential.Credential(secretId, secretKey)
  #http配置
  httpProfile = HttpProfile()
  httpProfile.endpoint = "vpc.tencentcloudapi.com"
  #客户端配置
  clientProfile.httpProfile = httpProfile
  # 地区选择是跟学校地域相关,腾讯沙箱云示例给的地区是广州
  client = cvm_client.CvmClient(cred, "ap-guangzhou", clientProfile)
  req = models.DescribeInstanceTypeConfigsRequest()
  params = '{}'
  req.from_json_string(params)
  resp = client.DescribeInstanceTypeConfigs(req)
  # 输出 JSON 格式的字符串回包
  dic = json.loads(resp.to_json_string())
  # 格式化输出json字符串 ensure_ascii False输出中文,4个缩进
  js = json.dumps(dic, ensure_ascii=False, indent=4)
  print(js)
except TencentCloudSDKException as err:
  print(err)

程序运行结果跟实际腾讯云沙箱中的CVM实例机型列表有关,由于机型列表输出较多,截取部分类似的输出如下:

{
  "InstanceTypeConfigSet": [
    {
      "Zone": "ap-guangzhou-2",
      "InstanceType": "S1.SMALL1",
      "InstanceFamily": "S1",
      "GPU": 0,
      "CPU": 1,
      "Memory": 1,
      "FPGA": 0
    },

10.4.4 查看VPC列表

DescribeVpcs接口是用于查询私有网络列表的,返回当前地域下所有VPC信息,DescribeVpcs接口支持金融区地域,接口请求域名vpc.tencentcloudapi.com。由于金融区和非金融区是隔离不互通的,因此当公共参数Region为金融区地域(如ap-shanghai-fsi)时,需要同时指定带金融区地域的域名,最好和Region的地域保持一致,如vpc.ap-shanghai-fsi.tencentcloudapi.com。具体代码如下:

# (DescribeVpcs)用于查询私有网络列表。
 import json
 from tencentcloud.common import credential
 from tencentcloud.common.profile.client_profile import ClientProfile
 from tencentcloud.common.profile.http_profile import HttpProfile
 from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
 from tencentcloud.vpc.v20170312 import vpc_client, models
 try:
   # 腾讯云教育沙箱中级第10章python验证上机的密钥
  const secretId = "yourSecretId"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  const secretKey = "yourSecretKey"  # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  #身份令牌配置
  cred = credential.Credential(secretId, secretKey)
  #http配置
  httpProfile = HttpProfile()
  httpProfile.endpoint = "vpc.tencentcloudapi.com"
  #客户端配置
  clientProfile = ClientProfile()
   clientProfile.httpProfile = httpProfile
   client = vpc_client.VpcClient(cred, "ap-guangzhou", clientProfile)
   req = models.DescribeVpcsRequest()
   params = '{}'
   req.from_json_string(params)
   resp = client.DescribeVpcs(req)
   # 输出 JSON 格式的字符串回包
   dic = json.loads(resp.to_json_string())
   # 格式化输出json字符串 ensure_ascii False输出中文,4个缩进
   js = json.dumps(dic, ensure_ascii=False, indent=4)
   print(js)
 except TencentCloudSDKException as err:
   print(err)

程序运行结果跟实际腾讯云沙箱中的VPC有关,类似的输出如下:

{
  "TotalCount": 1,
  "VpcSet": [
    {
      "VpcName": "Default-VPC",
      "VpcId": "vpc-92x5qecp",
      "CidrBlock": "172.16.0.0/16",
      "IsDefault": True,
      "EnableMulticast": False,
      "CreatedTime": "2020-04-26 14:44:40",
      "DnsServerSet": [
        "183.60.82.98",
        "183.60.83.19"
      ],
      "DomainName": "",
      "DhcpOptionsId": "dopt-3vetqofw",
      "EnableDhcp": True,
      "Ipv6CidrBlock": "",
      "TagSet": [],
      "AssistantCidrSet": []
    }
  ],
  "RequestId": "ffd33eee-71be-4780-aafb-719b3d191a44"
}

10.4.5 查看VPC下的云主机实例列表

DescribeVpcInstances接口是用来查看用户机器所在VPC下还有哪些其他机器,并给出云主机实例列表。接口请求域名为vpc.tencentcloudapi.com。本接口支持金融区地域。由于金融区和非金融区是隔离不互通的,因此当公共参数Region为金融区地域(如ap-shanghai-fsi)时,需要同时指定带金融区地域的域名,最好和Region的地域保持一致,如vpc.ap-shanghai-fsi.tencentcloudapi.com。具体代码如下:

# 查看VPC下的云主机实例列表 DescribeVpcInstances
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.vpc.v20170312 import vpc_client, models
try:
  # 腾讯云教育沙箱中级第10章python验证上机的密钥
  const secretId = "yourSecretId"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  const secretKey = "yourSecretKey"  # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  #身份令牌配置
  cred = credential.Credential(secretId, secretKey)
  #http配置
  httpProfile = HttpProfile()
  httpProfile.endpoint = "vpc.tencentcloudapi.com"
  #客户端配置
  clientProfile = ClientProfile()
  clientProfile.httpProfile = httpProfile
  client = vpc_client.VpcClient(cred, "ap-guangzhou", clientProfile)
  req = models.DescribeVpcInstancesRequest()
  # params不能为空
  params = '{"Filters":[{"Name":"vpc-id","Values":["vpc-92x5qecp"]}]}'
  req.from_json_string(params)
  resp = client.DescribeVpcInstances(req)
  dic = json.loads(resp.to_json_string())
  # 格式化输出json字符串 ensure_ascii False输出中文,4个缩进
  js = json.dumps(dic, ensure_ascii=False, indent=4)
  print(js)
except TencentCloudSDKException as err:
  print(err)

程序运行结果跟实际腾讯云沙箱中的云主机列表有关,类似的输出如下:

{
  "InstanceSet": [],
  "TotalCount": 0,
  "RequestId": "39e92f9a-2090-4de3-afc1-f2cbfc43020f"
}

10.4.6 查看子网列表

DescribeSubnets接口用于查看子网列表,支持金融区地域,接口请求域名为为vpc.tencentcloudapi.com。由于金融区和非金融区是隔离不互通的,因此当公共参数Region为金融区地域(例如ap-shanghai-fsi)时,需要同时指定带金融区地域的域名,最好和Region的地域保持一致,如vpc.ap-shanghai-fsi.tencentcloudapi.com。具体代码如下:

import json
 from tencentcloud.common import credential
 from tencentcloud.common.profile.client_profile import ClientProfile
 from tencentcloud.common.profile.http_profile import HttpProfile
 from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
 from tencentcloud.vpc.v20170312 import vpc_client, models
 try:
   # 腾讯云教育沙箱中级第10章python验证上机的密钥
  const secretId = "yourSecretId"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  const secretKey = "yourSecretKey"  # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140
  cred = credential.Credential(secretId, secretKey)
   #身份令牌配置
  cred = credential.Credential(secretId, secretKey)
  #http配置
  httpProfile = HttpProfile()
  httpProfile.endpoint = "vpc.tencentcloudapi.com"
  #客户端配置
  clientProfile.httpProfile = httpProfile
   client = vpc_client.VpcClient(cred, "ap-guangzhou", clientProfile)
  req = models.DescribeSubnetsRequest()
   params = '{}'
   req.from_json_string(params)
  resp = client.DescribeSubnets(req)
   # 输出 JSON 格式的字符串回包
   dic = json.loads(resp.to_json_string())
   # 格式化输出json字符串 ensure_ascii False输出中文,4个缩进
   js = json.dumps(dic, ensure_ascii=False, indent=4)
   print(js)
except TencentCloudSDKException as err:
   print(err)

程序运行结果跟实际腾讯云沙箱中的子网列表有关,类似的输出如下:

{
  "TotalCount": 1,
  "SubnetSet": [
    {
      "VpcId": "vpc-92x5qecp",
      "SubnetId": "subnet-h2ecwo2i",
      "SubnetName": "Default-Subnet",
      "CidrBlock": "172.16.0.0/20",
      "IsDefault": True,
      "EnableBroadcast": False,
      "Zone": "ap-guangzhou-3",
      "RouteTableId": "rtb-90vzabag",
      "CreatedTime": "2020-04-26 14:44:40",
      "AvailableIpAddressCount": 4093,
      "Ipv6CidrBlock": "",
      "NetworkAclId": "",
      "IsRemoteVpcSnat": False,
      "TotalIpAddressCount": 4093,
      "TagSet": []
    }
  ],
  "RequestId": "6128c712-cafb-449c-be40-9770297f8f83"
}

本章小结

本章以Python调用腾讯云API管理云资源为引导,介绍了Python语言的基本概念和Python开发工具安装及应用、Python程序编写以及常用第三库的安装及应用,并重点介绍了Python调用第三方库的应用。通过本章的学习,读者应能读懂Python代码,并可以编写、调试和运行代码。

本章习题

一、单项选择题

(1)关于Python内存管理,下列说法错误的是( )。

A.变量不必事先声明

B.变量无须先创建和赋值而直接使用

C.变量无须指定类型

D.可以使用del释放资源

2.下列哪个语句在Python中是非法的 ( )。

A.x = y = z = 1

B.x = (y = z + 1)

C.x, y = y, x

D.x += y

(3)Python不支持的数据类型有 ( )。

A.char

B.int

C.float

D.list

4.以下不能创建一个字典的语句是 ( )。

A.dict1 = {}

B.dict2 = { 3 : 5 }

C.dict3 = dict( 2 , 5 , 3 , 4 )

D.dict4 = dict( ( 1,2,3,4 ) )

5.下面不能创建一个集合的语句是( )。

A.s1 = set ()

B.s2 = set ("abcd")

C.s3 = (1, 2, 3, 4)

D.s4 = frozenset( (3,2,1) )

6.设s="Happy New Year",则s3:8的值为( )。

A. 'ppy Ne'

B. 'py Ne'

C. 'ppy N'

D. 'py New'

7.以下不能创建一个字典的语句是 ( )。

A. dict1 = {}

B. dict2 = { 1 : 2 }

C. dict3 = dict( 1 , 2 , 3 , 4 )

D. dict4 = dict( ( 1,2,3,4 ) )

二、问答题

1.字典(Dict)有什么特点?

2.列表(List)和元组(tuple)之间有什么相同点和区别?

3.分别描述Python面向对象编程中封装,继承,多态的含义和作用?