目录导航:
文章目录
- 目录导航:
- 一、Python基础
- 二、Python基础进阶
- 1.11 Python面向对象编程
- 1.12 Python中的异常处理
- 1.13 魔术方法、属性和迭代器
- 1.14 Python模块实战
- 1.15 MySQL数据库基础
- 1.16 Python的数据库支持
- 1.17 图形用户界面实战
- 1.18 阶段案例实战 :《飞机游戏》
- 1.19 Python扩展内容
一、Python基础
1.1 Python安装和使用
1.1.1 Python环境搭建
- Python可应用于多平台包括Windows、 Linux/Unix 和 Mac OS。
Python下载
- Python最新源码,二进制文档,新闻资讯等可以在Python的官网查看到:
- Python官网:http://www.python.org/
- 你可以在以下链接中下载 Python 的文档,你可以下载 HTML、PDF 和 PostScript 等格式的文档。
- Python文档下载地址:www.python.org/doc/
Unix & Linux 平台安装 Python:(源码式安装)
- 以下为在Unix & Linux 平台上安装 Python 的简单步骤:
- 打开WEB浏览器访问http://www.python.org/download/
- 选择适用于Unix/Linux的源码压缩包。
- 下载及解压压缩包。
- 如果你需要自定义一些选项修改Modules/Setup
- 执行 ./configure 脚本
- make
- make install
- 执行以上操作后,Python会安装在 /usr/local/bin 目录中,Python库安装在/usr/local/lib/pythonXX,XX为你使用的Python的版本号。
通过ubuntu官方的apt工具包安装
$ sudo apt-get install python
$ sudo apt-get install python2.7
$ sudo apt-get install python3.6
Mac安装Python3
$ brew sreach python
$ brew install python3
//在/usr/local/Cellar/这个目录下
Windows下直接下载安装就可以了
- 首先访问http://www.python.org/download/去下载最新的python版本
- 安装下载包,一路next,注意选择安装pip
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ftBqZi0g-1603700619101)(https://edu.csdn.net/notebook/python/images/week01/2017-12-14_191451.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEopZozG-1603700619103)(https://edu.csdn.net/notebook/python/images/week01/2017-12-14_191544.png)]
- 为计算机添加安装目录搭到环境变量,如图把python的安装目录添加到pth系统变量中即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L0gzjcFX-1603700619105)(https://edu.csdn.net/notebook/python/images/week01/11.png)]
1.1.2 运行Python
- 有三种方式可以运行Python:
(1) 交互式解释器
- 你可以通过命令行窗口进入python并开在交互式解释器中开始编写Python代码。
- 你可以在Unix,DOS或任何其他提供了命令行或者shell的系统进行python编码工作。
$ python # Unix/Linux
或者
C:>python # Windows/DOS
- 以下为Python命令行参数:
选项 | 描述 |
---|---|
-d | 在解析时显示调试信息 |
-O | 生成优化代码 ( .pyo 文件 ) |
-S | 启动时不引入查找Python路径的位置 |
-V | 输出Python版本号 |
-X | 从 1.6版本之后基于内建的异常(仅仅用于字符串)已过时。 |
-c cmd | 执行 Python 脚本,并将运行结果作为 cmd 字符串。 |
file | 在给定的python文件执行python脚本。 |
(2) 命令行脚本
- 在你的应用程序中通过引入解释器可以在命令行中执行Python脚本,如下所示:
$ python script.py # Unix/Linux
或者
C:>python script.py # Windows/DOS
(3) 集成开发环境(IDE:Integrated Development Environment): PyCharm
- PyCharm 是由 JetBrains 打造的一款 Python IDE,支持 macOS、 Windows、 Linux 系统。
- PyCharm 功能 : 调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制……
- PyCharm 下载地址 : https://www.jetbrains.com/pycharm/download/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gTvmmpiH-1603700619107)(https://edu.csdn.net/notebook/python/images/week01/22.png)]
1.2 Python基础语法
1.2.1 输入和输出
input()输入:
- input()的小括号中放入的是,提示信息,用来在获取数据之前给用户的一个简单提示
- input()在从键盘获取了数据以后,会存放到等号右边的变量中
- input()会把用户输入的任何值都作为字符串来对待
- 注意:在python2中还有一个raw_input()输入,但到python3中没有了
#!/usr/bin/python3
str = input("请输入:");
print ("你输入的内容是: ", str)
- 这会产生如下的对应着输入的结果:
请输入:Hello Python!
你输入的内容是: Hello Python!
Print()输出:
- print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":
#!/usr/bin/python3
x="a"
y="b"
# 换行输出
print( x )
print( y )
print('---------')
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
# 同时输出多个变量
print(x,y)
format的格式化函数(了解)
- 格式化字符串的函数 str.format(),它增强了字符串格式化的功能。
- 基本语法是通过 {} 和 : 来代替以前的 % 。
>>>"{} {}".format("hello", "world") # 不设置指定位置,按默认顺序
'hello world'
>>> "{0} {1}".format("hello", "world") # 设置指定位置
'hello world'
>>> "{1} {0} {1}".format("hello", "world") # 设置指定位置
'world hello world'
>>> print("网站名:{name}, 地址 {url}".format(name="百度", url="www.baidu.com")) #指定参数名
'网站名:百度, 地址 www.baidu.com'
>>>site = {"name": "百度", "url": "www.baidu.com"}
>>>print("网站名:{name}, 地址 {url}".format(**site)) # 通过字典设置参数
'网站名:百度, 地址 www.baidu.com'
>>>my_list = ['百度', 'www.baidu.com']
>>>print("网站名:{0[0]}, 地址 {0[1]}".format(my_list)) # "0" 是必须的 通过列表索引设置参数
'网站名:百度, 地址 www.baidu.com'
>>> print("{:.2f}".format(3.1415926)); #数字格式化
3.14
数字 | 格式 | 输出 | 描述 |
---|---|---|---|
3.1415926 | {:.2f} | 3.14 | 保留小数点后两位 |
3.1415926 | {:+.2f} | +3.14 | 带符号保留小数点后两位 |
-1 | {:+.2f} | -1.00 | 带符号保留小数点后两位 |
2.71828 | {:.0f} | 3 | 不带小数 |
5 | {:0>2d} | 05 | 数字补零 (填充左边, 宽度为2) |
5 | {:x<4d} | 5xxx | 数字补x (填充右边, 宽度为4) |
10 | {:x<4d} | 10xx | 数字补x (填充右边, 宽度为4) |
1000000 | {:,} | 1,000,000 | 以逗号分隔的数字格式 |
0.25 | {:.2%} | 25.00% | 百分比格式 |
1000000000 | {:.2e} | 1.00e+09 | 指数记法 |
13 | {:10d} | 13 | 右对齐 (默认, 宽度为10) |
13 | {:<10d} | 13 | 左对齐 (宽度为10) |
13 | {:^10d} | 13 | 中间对齐 (宽度为10) |
11 | ‘{:b}’.format(11) ‘{:d}’.format(11) ‘{😮}’.format(11) ‘{:x}’.format(11) ‘{:#x}’.format(11) ‘{:#X}’.format(11) | 1011 11 13 b 0xb 0XB | 进制 |
1.2.2 注释
Python中的注释有单行注释和多行注释:
- python中单行注释采用 # 开头。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:test.py
# 第一个注释
print "Hello, Python!"; # 第二个注释
输出结果:
Hello, Python!
注释可以在语句或表达式行末:
name = "Madisetti" # 这是一个注释
- python 中多行注释使用三个单引号(’’’)或三个双引号(""")。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:test.py
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。
这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
1.2.3 标识符
-
在
Python
里,标识符: 由字母、数字、下划线组成,但不能以数字开头
。 -
Python 中的标识符是区分大小写的。
-
特殊标识符:
- 以下划线开头的标识符是有特殊意义的。以单下划线开头
_foo
的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用from xxx import *
而导入; - 以双下划线开头的
__foo
代表类的私有成员;以双下划线开头和结尾的__foo__
代表 Python 里特殊方法专用的标识,如__init__()
代表类的构造函数。
- 以下划线开头的标识符是有特殊意义的。以单下划线开头
-
python保留字: 保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
>>> import keyword >>> keyword.kwlist ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'if', 'return','try', 'while', 'with', 'yield']
1.2.4 变量
- Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
- 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。
- 等号(=)用来给变量赋值。
- 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。例如:
- 实例(Python 3.0+)
#!/usr/bin/python3
counter = 100 # 整型变量
miles = 1000.0 # 浮点型变量
name = "demo" # 字符串
print (counter)
print (miles)
print (name)
-
执行以上程序会输出如下结果:
100 1000.0 demo
多个变量赋值
-
Python允许你同时为多个变量赋值。例如:
a = b = c = 1
-
以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上。
-
您也可以为多个对象指定多个变量。例如:
a, b, c = 1, 2, "demo"
-
以上实例,两个整型对象 1 和 2 的分配给变量 a 和 b,字符串对象 “demo” 分配给变量 c。
1.2.5 行与缩进
- python最具特色的就是使用缩进来表示代码块,不需要使用大括号({})。
- 缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。实例如下:
if True:
print ("True")
else:
print ("False")
- 以下代码最后一行语句缩进数的空格数不一致,会导致运行错误:
if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
- 以上程序由于缩进不一致,执行后会出现类似以下错误:
File "test.py", line 6
print ("False") # 缩进不一致,会导致运行错误
^
IndentationError: unindent does not match any outer indentation level
多行语句
- Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠()来实现多行语句,例如:
total = item_one + \
item_two + \
item_three
- 在 [], {}, 或 () 中的多行语句,不需要使用反斜杠(),例如:
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
空行
- 函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
- 空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
- 记住:空行也是程序代码的一部分。
1.3 Python运算符
- 本章节主要说明Python的运算符。举个简单的例子 4 +5 = 9 。 例子中,4 和 5 被称为操作数,"+" 称为运算符。
- Python语言支持以下类型的运算符:
- 算术运算符
- 比较(关系)运算符
- 赋值运算符
- 逻辑运算符
- 位运算符
- 成员运算符
- 身份运算符
- 运算符优先级
(1) Python算术运算符
- 以下假设变量a为10,变量b为21:
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果 31 |
- | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次字串 | a * b 输出结果 210 |
/ | 除 - x 除以 y | b / a 输出结果 2.1 |
% | 取模 - 返回除法的余数 | b % a 输出结果 1 |
** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
// | 取整除 - 返回商的整数部分 | 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
(2) Python比较运算符
- 以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True。 |
> | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
< | 小于 - 返回x是否小于y。返回1表示真,返回0表示假。 这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | (a < b) 返回 True。 |
>= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
<= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
(3) Python赋值运算符
- 以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
(4) Python位运算符
- 按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下:
- 下表中变量 a 为 60,b 为 13二进制格式如下:
>>> a=18
>>> bin(a) # 将变量a的数值转成二进制数值输出
'0b10010'
>>> b = 0b10010 #将二进制的数值赋给变量b
>>> b
18
# 下面是二进制运算
a = 0011 1100
b = 0000 1101
-----------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
l | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a l b) 输出结果 61 ,二进制解释: 0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
>> | 右移动运算符:把">>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
(5) Python逻辑运算符
- Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20:
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |
or | x or y | 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
(6) Python成员运算符
- 除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
#!/usr/bin/python3
a = 10
b = 20
list = [1, 2, 3, 4, 5 ];
if ( a in list ):
print ("1 - 变量 a 在给定的列表中 list 中")
else:
print ("1 - 变量 a 不在给定的列表中 list 中")
if ( b not in list ):
print ("2 - 变量 b 不在给定的列表中 list 中")
else:
print ("2 - 变量 b 在给定的列表中 list 中")
# 修改变量 a 的值
a = 2
if ( a in list ):
print ("3 - 变量 a 在给定的列表中 list 中")
else:
print ("3 - 变量 a 不在给定的列表中 list 中")
以上实例输出结果:
1 - 变量 a 不在给定的列表中 list 中
2 - 变量 b 不在给定的列表中 list 中
3 - 变量 a 在给定的列表中 list 中
(7) Python身份运算符
- 身份运算符用于比较两个对象的存储单元
运算符 | 描述 | 实例 |
---|---|---|
is | is是判断两个标识符是不是引用自一个对象 | x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
- 注:
id()
函数用于获取对象内存地址。
#!/usr/bin/python3
a = 20
b = 20
if ( a is b ):
print ("1 - a 和 b 有相同的标识")
else:
print ("1 - a 和 b 没有相同的标识")
if ( id(a) == id(b) ):
print ("2 - a 和 b 有相同的标识")
else:
print ("2 - a 和 b 没有相同的标识")
# 修改变量 b 的值
b = 30
if ( a is b ):
print ("3 - a 和 b 有相同的标识")
else:
print ("3 - a 和 b 没有相同的标识")
if ( a is not b ):
print ("4 - a 和 b 没有相同的标识")
else:
print ("4 - a 和 b 有相同的标识")
- 以上实例输出结果:
1 - a 和 b 有相同的标识
2 - a 和 b 有相同的标识
3 - a 和 b 没有相同的标识
4 - a 和 b 没有相同的标识
is 与 == 区别:
# is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
>>>a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:] # 其中[:]表示复制传值
>>> b is a
False
>>> b == a
True
(8) Python运算符优先级
- 以下表格列出了从最高到最低优先级的所有运算符:
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 ‘AND’ |
^ l | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not or and | 逻辑运算符 |
1.4 Python数据类型
1.4.1 标准数据类型
- Python3 中有六个标准的数据类型:
- Number(数字)
- int
- bool
- float
- complex(复数)
- String(字符串)
- List(列表)
- Tuple(元组)
- Sets(集合)
- Dictionary(字典)
- Number(数字)
(1) Number(数字)
- Python3 支持 int、float、bool、complex(复数)。
- 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
- 像大多数语言一样,数值类型的赋值和计算都是很直观的。
- 内置的 type() 函数可以用来查询变量所指的对象类型。
>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
- 此外还可以用 isinstance 来判断:
>>>a = 111
>>> isinstance(a, int)
True
>>>
- isinstance 和 type 的区别在于:
class A:
pass
class B(A):
pass
isinstance(A(), A) # returns True
type(A()) == A # returns True
isinstance(B(), A) # returns True
type(B()) == A # returns False
- 区别就是:
- type()不会认为子类是一种父类类型。
- isinstance()会认为子类是一种父类类型。
注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。
到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。
- 当你指定一个值时,Number 对象就会被创建:
var1 = 1
var2 = 10
- 您也可以使用del语句删除一些对象引用。
- del语句的语法是:
- del var1[,var2[,var3[…,varN]]]]
- 您可以通过使用del语句删除单个或多个对象。例如
del var
del var_a, var_b
整数的进制:
# 输出其他进制数值
>>> bin(255) #255的二进制
'0b11111111'
>>> oct(255) #255的八进制
'0o377'
>>> hex(255) #255的十六进制
'0xff'
>>> a=0b10 #赋值二进制数值
>>> a
2
>>> a=0o10 #赋值八进制数值
>>> a
8
>>> a=0x10 #赋值十六进制数值
>>> a
16
(2) String(字符串)
- Python中的字符串用单引号(’)或双引号(")括起来,同时使用反斜杠()转义特殊字符。
- 字符串的截取的语法格式如下:
变量[头下标:尾下标]
- 索引值以 0 为开始值,-1 为从末尾的开始位置。
- 加号 (+) 是字符串的连接符, 星号 (*) 表示复制当前字符串,紧跟的数字为复制的次数。实例如下:
#!/usr/bin/python3
str = 'zhangsan'
print (str) # 输出字符串
print (str[0:-1]) # 输出第一个到倒数第二个的所有字符
print (str[0]) # 输出字符串第一个字符
print (str[2:5]) # 输出从第三个开始到第五个的字符
print (str[2:]) # 输出从第三个开始的后的所有字符
print (str * 2) # 输出字符串两次
print (str + "TEST") # 连接字符串
- 输出结果:
zhangsan
zhangsa
z
ang
angsan
zhangsanzhangsan
zhangsanTEST
- Python 使用反斜杠()转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个
r
,表示原始字符串:
>>> print('Ru\noob')
Ru
oob
>>> print(r'Ru\noob')
Ru\noob
>>>
- 另外,反斜杠()可以作为续行符,表示下一行是上一行的延续。也可以使用 “”"…""" 或者 ‘’’…’’’ 跨越多行。
- 注意,Python 没有单独的字符类型,一个字符就是长度为1的字符串。
>>>word = 'Python'
>>> print(word[0], word[5])
P n
>>> print(word[-1], word[-6])
n P
- 与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如word[0] = 'm’会导致错误。
- 注意:
- 1、反斜杠可以用来转义,使用
r
可以让反斜杠不发生转义。 - 2、字符串可以用+运算符连接在一起,用
*
运算符重复。 - 3、Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。
- 4、Python中的字符串不能改变。
- 1、反斜杠可以用来转义,使用
(3) List(列表)
- List(列表) 是 Python 中使用最频繁的数据类型。
- 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
- 列表是写在方括号
[]
之间、用逗号分隔开的元素列表。 - 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
- 列表截取的语法格式如下:
变量[头下标:尾下标]
- 索引值以 0 为开始值,-1 为从末尾的开始位置。
- 加号(+)是列表连接运算符,星号(*)是重复操作。如下实例:
#!/usr/bin/python3
list = [ 'abcd', 786 , 2.23, 'demo', 70.2 ]
tinylist = [123, 'demo']
print (list) # 输出完整列表
print (list[0]) # 输出列表第一个元素
print (list[1:3]) # 从第二个开始输出到第三个元素
print (list[2:]) # 输出从第三个元素开始的所有元素
print (tinylist * 2) # 输出两次列表
print (list + tinylist) # 连接列表
-
以上实例输出结果:
['abcd', 786, 2.23, 'demo', 70.2] abcd [786, 2.23] [2.23, 'demo', 70.2] [123, 'demo', 123, 'demo'] ['abcd', 786, 2.23, 'demo', 70.2, 123, 'demo']
-
与Python字符串不一样的是,列表中的元素是可以改变的:
>>>a = [1, 2, 3, 4, 5, 6]
>>> a[0] = 9
>>> a[2:5] = [13, 14, 15]
>>> a
[9, 2, 13, 14, 15, 6]
>>> a[2:5] = [] # 将对应的元素值设置为 []
>>> a
[9, 2, 6]
- List内置了有很多方法,例如append()、pop()等等,这在后面会讲到。
*注意:
* 1、List写在方括号之间,元素用逗号隔开。
* 2、和字符串一样,list可以被索引和切片。
* 3、List可以使用+操作符进行拼接。
* 4、List中的元素是可以改变的。
(4) Tuple(元组)
- 元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号(())里,元素之间用逗号隔开。
- 元组中的元素类型也可以不相同:
#!/usr/bin/python3
tuple = ( 'abcd', 786 , 2.23, 'demo', 70.2 )
tinytuple = (123, 'demo')
print (tuple) # 输出完整元组
print (tuple[0]) # 输出元组的第一个元素
print (tuple[1:3]) # 输出从第二个元素开始到第三个元素
print (tuple[2:]) # 输出从第三个元素开始的所有元素
print (tinytuple * 2) # 输出两次元组
print (tuple + tinytuple) # 连接元组
-
以上实例输出结果:
('abcd', 786, 2.23, 'demo', 70.2) abcd (786, 2.23) (2.23, 'demo', 70.2) (123, 'demo', 123, 'demo') ('abcd', 786, 2.23, 'demo', 70.2, 123, 'demo')
-
元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置。
-
也可以进行截取(看上面,这里不再赘述)。
-
其实,可以把字符串看作一种特殊的元组。
>>>tup = (1, 2, 3, 4, 5, 6)
>>> print(tup[0])
1
>>> print(tup[1:5])
(2, 3, 4, 5)
>>> tup[0] = 11 # 修改元组元素的操作是非法的
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
- 虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。
- 构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:
tup1 = () # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
string、list和tuple都属于sequence(序列)。
- 注意:
- 1、与字符串一样,元组的元素不能修改。
- 2、元组也可以被索引和切片,方法一样。
- 3、注意构造包含0或1个元素的元组的特殊语法规则。
- 4、元组也可以使用+操作符进行拼接。
(5) Set(集合)
- 集合(set)是一个无序不重复元素的序列。
- 基本功能是进行成员关系测试和删除重复元素。
- 可以使用大括号
{ }
或者set()
函数创建集合,注意:创建一个空集合必须用set()
而不是{ }
,因为{ }
是用来创建一个空字典。 - 创建格式:
parame = {value01,value02,...}
或者
set(value)
- 实例:
#!/usr/bin/python3
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
print(student) # 输出集合,重复的元素被自动去掉
# 成员测试
if('Rose' in student) :
print('Rose 在集合中')
else :
print('Rose 不在集合中')
# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(a - b) # a和b的差集
print(a | b) # a和b的并集
print(a & b) # a和b的交集
print(a ^ b) # a和b中不同时存在的元素
- 以上实例输出结果:
{'Mary', 'Jim', 'Rose', 'Jack', 'Tom'}
Rose 在集合中
{'b', 'a', 'c', 'r', 'd'}
{'b', 'd', 'r'}
{'l', 'r', 'a', 'c', 'z', 'm', 'b', 'd'}
{'a', 'c'}
{'l', 'r', 'z', 'm', 'b', 'd'}
(6) Dictionary(字典)
- 字典(dictionary)是Python中另一个非常有用的内置数据类型。
- 列表是有序的对象结合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
- 字典是一种映射类型,字典用"{ }"标识,它是一个无序的键(key) : 值(value)对集合。
- 键(key)必须使用不可变类型。
- 在同一个字典中,键(key)必须是唯一的。
#!/usr/bin/python3
dict = {}
dict['one'] = "1 - Python教程"
dict[2] = "2 - Python工具"
tinydict = {'name': 'demo','code':1, 'site': 'www.demo.com'}
print (dict['one']) # 输出键为 'one' 的值
print (dict[2]) # 输出键为 2 的值
print (tinydict) # 输出完整的字典
print (tinydict.keys()) # 输出所有键
print (tinydict.values()) # 输出所有值
以上实例输出结果:
1 - Python教程
2 - Python工具
{'name': 'demo', 'site': 'www.demo.com', 'code': 1}
dict_keys(['name', 'site', 'code'])
dict_values(['demo', 'www.demo.com', 1])
- 构造函数 dict() 可以直接从键值对序列中构建字典如下:
- 实例
>>>dict([('demo', 1), ('Google', 2), ('Taobao', 3)])
{'Taobao': 3, 'demo': 1, 'Google': 2}
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
>>> dict(demo=1, Google=2, Taobao=3)
{'Taobao': 3, 'demo': 1, 'Google': 2}
- 另外,字典类型也有一些内置的函数,例如clear()、keys()、values()等。
- 注意:
- 1、字典是一种映射类型,它的元素是键值对。
- 2、字典的关键字必须为不可变类型,且不能重复。
- 3、创建空字典使用 { }。
1.4.2 Python数据类型转换
- 有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。
- 以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值
函数 | 描述 |
---|---|
int(x [,base]) | 将x转换为一个整数 |
float(x) | 将x转换到一个浮点数 |
complex(real [,imag]) | 创建一个复数 |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
set(s) | 转换为可变集合 |
dict(d) | 创建一个字典。d 必须是一个序列 (key,value)元组。 |
frozenset(s) | 转换为不可变集合 |
chr(x) | 将一个整数转换为一个字符 |
unichr(x) | 将一个整数转换为Unicode字符 |
ord(x) | 将一个字符转换为它的整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
oct(x) | 将一个整数转换为一个八进制字符串 |
数据类型转换分类:
- 数据类型转换一共分为2类:自动数据类型转换(隐式转换)和强制数据类型转换(显示转换)
自动数据类型转换/隐式转换
- 自动类型转换是程序根据运算要求进行的转换,不需要人工干预 1.自动类型转换不需要人工干预 2.自动类型转换多发生在运算或者判断过程中 3.转化时向着更加精确的类型转换
强制类型转换/显示转换
- 根据程序需要,由编写程序人员人为改变数据类型的方式就是强制数据类型转换。
- int() 将其他类型转化为整型
1.数字整型转化之后,还是原来的味道
2.浮点类型转化之后,舍去小数部分
3.布尔值转化之后 True -> 1 False->0
4.字符串转换,仅纯整型字符串可以转化(浮点型或者带有其他字符都不可以转化)
5.复数不可以转换
- float() 将其他类型转化为浮点型
1.整型转换之后变为浮点型,后面+.0
2.浮点数不需要转化,转化也不会变化
3.布尔值转化 True->1.0 False ->0.0
4.字符串,纯整型字符串和纯浮点型字符串可以转换,其他都不可以
- complex() 将其他数据转化为复数
1.整型转换之后变为 (整型+0j)
2.浮点型转换之后变为(浮点型 + 0j)
3.布尔值转化之后 True->(1+0j) False(0j)
4.字符串,纯整型和浮点型字符串可以转化,其他都不行
5.复数,无需转换
- bool() 将其他类型转化为布尔值
#下面转化为布尔值false的情况
1.整型 0
2.浮点型 0.0
3.复数 0+0j
4.布尔 False
5.字符串 '' 空字符串
6.列表 [] 空列表
7.元组 ()空元组
8.字典 {} 空字典
9.集合 set() 空集合
- str() 将其他类型转化为字符串
- 所有转换均改变类型为字符串,表示方式依旧不变
- list() 将其他类型转化为列表类型
- 在python中有5中可迭代序列,可以互相转换,他们分别是:
- 字符串,列表,元组,字典,集合
var = ('张三','李四','王老五')
newvar = list(var)
newvar的值为 ['张三','李四','王老五']
注意:
- 1.字符串转换时每个字符变成列表中的一个值
- 2.字典类型转换时,仅将字典的键部分转换成列表,忽略值部分
- tuple() 将其他类型转化为元组类型
var = {'张三','李四','王老五'}
newvar = tuple(var)
newvar的值为 ('张三','李四','王老五')
-
注意:
- 1.字符串转换时每个字符变成元组中的一个值
- 2.字典类型转换时,仅将字典的键部分转换成元组,忽略值部分
-
set() 将其他类型转化为集合类型
var = ['张三','李四','王老五']
newvar = set(var)
newvar的值为 {'张三','李四','王老五'} #值的顺序不定
-
注意:
- 1.字符串转换时每个字符变成集合中的一个值
- 2.字典类型转换时,仅将字典的键部分转换集合,忽略值部分
-
dict() 将其他类型转换为字典类型
-
其他类型转化为字典时需要按照指定的格式才可以转化:(列表和元组的组合可以)
[['cat', '黑猫警长'], ['mouse', '一只耳'], ['next', '请看夏季']]
[('cat', '黑猫警长'), ('mouse', '一只耳'), ('next', '请看夏季')]
1.5 Python分支结构
1.5.1 流程控制
流程
: 计算机执行代码的顺序就是流程流程控制
: 对计算机代码执行顺序的管理就是流程控制流程分类
: 流程控制一共分为三类:- 顺序结构
- 分支结构/选择结构
- 循环结构
1.5.2 分支/选择结构
- 分支结构一共分为4类:
- 单项分支
- 双项分支
- 多项分支
- 巢状分支
(1) 单项分支
if 条件表达式:
一条python语句...
一条python语句...
...
- 特征:
- if条件表达式结果为真,则执行if之后所控制代码组,如果为假,则不执行后面的代码组(
:
后面的N行中有相同缩进的代码) :
之后下一行的内容必须缩进,否则语法错误!- if之后的代码中如果缩进不一致,则不会if条件表达式是的控制,也不是单项分支的内容,是顺序结构的一部分
- if
:
后面的代码是在条件表达式结果为真的情况下执行,所以称之为真区间或者if区间、
- if条件表达式结果为真,则执行if之后所控制代码组,如果为假,则不执行后面的代码组(
(2) 双项分支
if 条件表达式:
一条python语句...
一条python语句...
...
else:
一条python语句...
一条python语句...
...
- 特征:
- 1.双项分支有2个区间:分别是True控制的if区间和False控制的else区间(假区间)
- 2.if区间的内容在双项分支中必须都缩进,否则语法错误!
(2) 多项分支
if 条件表达式:
一条python语句...
一条python语句...
...
elif 条件表达式:
一条python语句...
一条python语句...
...
elif 条件表达式:
一条python语句...
一条python语句...
...
...
else:
一条python语句...
一条python语句...
- 特征:
- 1.多项分支可以添加无限个elif分支,无论如何只会执行一个分支
- 2.执行完一个分支后,分支结构就会结束,后面的分支都不会判断也不会执行
- 3.多项分支的判断顺序是自上而下逐个分支进行判断
- 4.在Python中没有switch – case语句。
- 实例-演示了狗的年龄计算判断:
#!/usr/bin/python3
age = int(input("请输入你家狗狗的年龄: "))
print("")
if age < 0:
print("你是在逗我吧!")
elif age == 1:
print("相当于 14 岁的人。")
elif age == 2:
print("相当于 22 岁的人。")
elif age > 2:
human = 22 + (age -2)*5
print("对应人类年龄: ", human)
### 退出提示
input("点击 enter 键退出")
(4) 巢状分支
- 巢状分支是其他分支结构的嵌套结构,无论哪个分支都可以嵌套
# !/usr/bin/python3
num=int(input("输入一个数字:"))
if num%2==0:
if num%3==0:
print ("你输入的数字可以整除 2 和 3")
else:
print ("你输入的数字可以整除 2,但不能整除 3")
else:
if num%3==0:
print ("你输入的数字可以整除 3,但不能整除 2")
else:
print ("你输入的数字不能整除 2 和 3")
- 将以上程序保存到 test_if.py 文件中,执行后输出结果为:
$ python3 test.py
输入一个数字:6
你输入的数字可以整除 2 和 3
1.6 Python循环结构
- 循环结构就是为了将相似或者相同的代码操作变得更见简洁,使得代码可以重复利用
- 循环结构分为2类:
while
循环 和for..in
循环
1.6.1 while型循环
格式1:
while 条件表达式:
循环的内容
[变量的变化]
格式2:
while 条件表达式:
循环的内容
[变量的变化]
else:
python语句..
- 注意:while循环中的else是在while条件表达式为假的情况下执行的代码内容,一般用于判断起始条件是否为假等相关操作。
- 实例使用了 while 来计算 1 到 100 的总和:
#!/usr/bin/env python3
n = 100
sum = 0
counter = 1
while counter <= n:
sum = sum + counter
counter += 1
print("1 到 %d 之和为: %d" % (n,sum))
- 执行结果如下:
1 到 100 之和为: 5050
死循环:
- 死循环就是循环不会终止的循环类型,通过将用于判断的条件表达式设置为永远为True来实现。
while True:
python代码...
python代码...
...
#!/usr/bin/python3
var = 1
while var == 1 : # 表达式永远为 true
num = int(input("输入一个数字 :"))
print ("你输入的数字是: ", num)
print ("Good bye!")
- 你可以使用 CTRL+C 来退出当前的无限循环
- 执行以上脚本,输出结果如下:
输入一个数字 :5
你输入的数字是: 5
输入一个数字 :
1.6.2 for … in 循环
- for…in 循环用于遍历容器类的数据(字符串,列表,元组,字典,集合)
格式:
for 变量 in 容器:
python代码,可以在此使用变量
格式2:
for 变量1,变量2 in 容器:
python代码,可以在此使用变量1和变量2
- 要求遍历的容器必须是一下几种格式:
- [(),(),()] 列表中有元组
- [[],[],[]] 列表中有列表
- ((),(),()) 元组中有元组
- {(),(),()} 集合中有元组
- 字典的特殊使用
格式3:
for 变量 in 容器:
python代码,可以在此使用变量
else:
循环结束是执行的代码!
>>>languages = ["C", "C++", "Perl", "Python"]
>>> for x in languages:
... print (x)
...
C
C++
Perl
Python
>>>
1.6.3 range()函数
- 如果你需要遍历数字序列,可以使用内置range()函数。它会生成数列,例如:
>>>for i in range(5):
... print(i)
...
0
1
2
3
4
>>>for i in range(5,9) :
print(i)
5
6
7
8
>>>
>>>for i in range(0, 10, 3) :
print(i)
0
3
6
9
>>>
>>>for i in range(-10, -100, -30) :
print(i)
-10
-40
-70
>>>
- 您可以结合range()和len()函数以遍历一个序列的索引,如下所示:
>>>a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
>>>
输出乘法口诀:
for i in range(1,10):
for j in range(1,i+1):
print(str(i)+'*'+str(j)+"="+str(i*j),end="")
print()
1.3.7 练习:逆向输出乘法口诀
for i in range(9,0,-1):
for j in range(i,0,-1):
print(str(i)+'*'+str(j)+"="+str(i*j),end="\t")
print()
1.6.4 break和continue语句及循环中的else子句
break语句:
- break作用:在循环中break的作用是终止当前循环结构的后续操作,一旦程序运行了break,循环也就终止了!
- break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。 实例如下:
#!/usr/bin/python3
for letter in 'Runoob': # 第一个实例
if letter == 'b':
break
print ('当前字母为 :', letter)
var = 10 # 第二个实例
while var > 0:
print ('当期变量值为 :', var)
var = var -1
if var == 5:
break
print ("Good bye!")
- 执行以上脚本输出结果为:
当前字母为 : R
当前字母为 : u
当前字母为 : n
当前字母为 : o
当前字母为 : o
当期变量值为 : 10
当期变量值为 : 9
当期变量值为 : 8
当期变量值为 : 7
当期变量值为 : 6
Good bye!
continue语句:
- continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
#!/usr/bin/python3
for letter in 'Runoob': # 第一个实例
if letter == 'o': # 字母为 o 时跳过输出
continue
print ('当前字母 :', letter)
var = 10 # 第二个实例
while var > 0:
var = var -1
if var == 5: # 变量为 5 时跳过输出
continue
print ('当前变量值 :', var)
print ("Good bye!")
- 执行以上脚本输出结果为:
当前字母 : R
当前字母 : u
当前字母 : n
当前字母 : b
当前变量值 : 9
当前变量值 : 8
当前变量值 : 7
当前变量值 : 6
当前变量值 : 4
当前变量值 : 3
当前变量值 : 2
当前变量值 : 1
当前变量值 : 0
Good bye!
- 循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。
- 如下实例用于查询质数的循环例子:
#!/usr/bin/python3
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, '等于', x, '*', n//x)
break
else:
# 循环中没有找到元素
print(n, ' 是质数')
- 执行以上脚本输出结果为:
2 是质数
3 是质数
4 等于 2 * 2
5 是质数
6 等于 2 * 3
7 是质数
8 等于 2 * 4
9 等于 3 * 3
pass 语句:
- Python pass是空语句,是为了保持程序结构的完整性。
- pass 不做任何事情,一般用做占位语句,如下实例
>>>while True:
... pass # 等待键盘中断 (Ctrl+C)
最小的类:
>>>class MyEmptyClass:
... pass
1.7 Python函数
1.7.1 认识Python函数
- 函数的本质就是功能的封装。使用函数可以大大提高编程效率与程序的可读性。
- 函数是能够实现特定功能的计算机代码而已,他是一种特定的代码组结构。
- 函数的作用
- 1.提升代码的重复利用率,避免重复开发相同代码
- 2.提高程序开发效率
- 3.便于程序维护
定义一个函数:
- 你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
1.7.2 函数的定义格式
- 基本函数格式
- 带有参数的函数格式
- 带有默认值的参数
- 关键字参数
- 收集参数(带*)
- 多种参数混合
(1) 基本函数格式
def 函数名():
函数功能代码...
函数功能代码...
...
调用函数: 函数名()
- 特征:函数定义之后不会自动执行,必须在调用函数后函数才会执行.
- 函数名的命名规则:和变量基本一样
- 1.推荐使用英文或者拼音,禁止使用中文
- 2.可以使用数字,但是不能用数字开头
- 3.不可以使用特殊字符,除了_
- 4.函数名严格区分大小写
- 5.函数名必须要有意义。
- 6.不能和系统已经存在的保留关键字冲突!
- 7.禁止使用和系统提供函数相同的函数名
- 让我们使用函数来输出"Hello World!":
>>> def hello() :
print("Hello World!")
>>> hello()
Hello World!
>>>
(2) 带有参数的函数格式
def 函数名(参数,参数...):
函数功能代码...
函数功能代码...
...
调用函数:函数名(参数,参数...)
形参:形式上的参数,声明函数时()中的参数是形参
实参:实际上的参数,调用函数时()中的参数是实参
注意:实参将值传递给形参的过程本质上就是简单的变量赋值仅此而已
- 更复杂点的应用,函数中带上参数变量:
#!/usr/bin/python3
# 计算面积函数
def area(width, height):
return width * height
def print_welcome(name):
print("Welcome", name)
print_welcome("Python")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))
- 以上实例输出结果:
Welcome Python
width = 4 height = 5 area = 20
- 参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
- 调用printme()函数,你必须传入一个参数,不然会出现语法错误:
#!/usr/bin/python3
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str);
return;
#调用printme函数
printme();
- 以上实例输出结果:
Traceback (most recent call last):
File "test.py", line 10, in <module>
printme();
TypeError: printme() missing 1 required positional argument: 'str'
(3) 带有默认值的参数
def 函数名(形参=默认值,形参=默认值...):
函数功能代码...
函数功能代码...
...
调用函数:
函数名() 调用函数时所有形参采用默认值操作
函数名(实参,实参...) 调用时形参使用实参的值而抛弃默认值
- 注意:在此情况下使用实参值覆盖原有形参的默认值,本质上就是变量的重新赋值操作
- 调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:
#!/usr/bin/python3
#可写函数说明
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name);
print ("年龄: ", age);
return;
#调用printinfo函数
printinfo( age=50, name="runoob" );
print ("------------------------")
printinfo( name="runoob" );
- 输出结果
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
(4) 关键字参数
def 函数名(形参=默认值,形参=默认值...):
函数功能代码...
函数功能代码...
...
调用函数:函数名(形参=实参,形参=实参...)
- 关键字参数就是调用函数时,在实参前面指定形参的做法,为了防止参数按照位置传递出现的错误
- 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
- 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
- 以下实例在函数 printme() 调用时使用参数名:
#!/usr/bin/python3
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str);
return;
#调用printme函数
printme( str = "Python教程");
- 以上实例输出结果:
Python教程
- 以下实例中演示了函数参数的使用不需要使用指定顺序:
#!/usr/bin/python3
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name);
print ("年龄: ", age);
return;
#调用printinfo函数
printinfo( age=50, name="runoob" );
- 以上实例输出结果:
名字: runoob
年龄: 50
(5). 收集参数
- 1.非关键字收集参数
def 函数名(*参数名):
函数功能代码...
函数功能代码...
...
调用函数:函数名(实参,实参...) 没有数量限制
- 特征:
- 1.非关键字收集参数,在形参前添加一个*即可
- 2.非关键字收集参数收集实参组成一个元组
- 3.非关键字收集参数,仅收集没有任何形参接受的非关键字实参
- 4.非关键字收集参数和普通的形参可以共存
#!/usr/bin/python3
# 可写函数说明
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
for var in vartuple:
print (var)
return;
# 调用printinfo 函数
printinfo( 10 );
printinfo( 70, 60, 50 );
- 以上实例输出结果:
输出:
10
输出:
70
60
50
- 2.关键字收集参数
def 函数名(**参数名):
函数功能代码...
函数功能代码...
...
调用函数: 函数名(形参=实参,形参=实参...) 没有数量限制
- 特征:
- 1.关键字收集参数,在形参前添加两个**即可
- 2.关键字收集参数,收集的结果组成一个字典,关键字成为字典的键,实参成为值
- 3.关键字收集参数,仅收集没有任何形参接受的关键字参数
- 4.关键字参数可以和普通的形参共存
#定义
def func(country,province,**kwargs):
print(country,province,kwargs)
#使用
func("China","Sichuan",city = "Chengdu", section = "JingJiang")
# 结果
# China Sichuan {'city': 'Chengdu', 'section': 'JingJiang'}
(6) 多种参数混合
- 定义函数时尽量避免多种参数格式混合(普通参数/非关键字参数,关键字参数,非关键字收集参数,关键字收集参数)
- 1.普通参数(非关键字参数)和关键字参数必须在两种收集参数之前
- 2.非关键字收集参数,必须在关键字收集参数之前
- 3.如果多种参数在一起,必须注意进制参数多次赋值操作(相同赋值赋值之后,关键字参数在此赋值!)
**关于返回值的问题
- 函数根据执行完毕是否可以得到一个结果,将函数分为2个类型:
- 执行过程函数:print()
- 函数执行完毕之后,不会有任何结果可以被接受的函数。
- 具有返回值的函数:id(),type()
- 函数执行完毕之后,会产生一个结果,可以被变量接受或者使用的函数
- 执行过程函数:print()
格式:
def 函数名(参数....):
函数功能代码...
函数功能代码...
...
[return 语句]
- return的特征:
- 1.具有return语句的函数称为具有返回值的函数
- 2.return可以为当前函数执行完毕返回一个结果,这样的函数调用可以被接受
- 3.return执行之后,函数则会终止,所有return之后的语句不会被执行
- 4.一个函数可以书写多个return语句,但是一般会放入分支结构当中。
- 5.一个函数如果需要返回多个数据,需要借助复合数据类型(list,tuple,set,dict)来操作即可!
- 6.不带参数值的return语句返回None。之前的例子都没有示范如何返回数值.
#!/usr/bin/python3
# 可写函数说明
def sum( arg1, arg2 ):
# 返回2个参数的和."
total = arg1 + arg2
print ("函数内 : ", total)
return total;
# 调用sum函数
total = sum( 10, 20 );
print ("函数外 : ", total)
- 以上实例输出结果:
函数内 : 30
函数外 : 30
1.7.3 函数文档
- 函数文档就是用来查看当前函数相关信息介绍的一个特定格式而已。
- 查看函数文档的方法:
help(函数名称)
直接输出显示函数文档的内容字符串
函数名.__doc__
直接输出显示函数文档的内容元字符串(转义字符不转义)
- 定义函数的文档:
def 函数名(参数...):
'''
在此处声明函数文档
'''
函数功能代码...
函数功能代码...
。。。
或者:
def 函数名(参数...):
"""
在此处声明函数文档
"""
函数功能代码...
函数功能代码...
。。。
- 注意:函数文档的作用是对函数进行说明,便于阅读和快速掌握函数的使用,通常函数文档需要具有以下信息:
- 函数的作用
- 函数的参数介绍(个数,数据类型)
- 函数的返回值(数据和类型)
1.7.4 局部变量与全局变量
- 定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
- 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:
#!/usr/bin/python3
total = 0; # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2; # total在这里是局部变量.
print ("函数内是局部变量 : ", total)
return total;
#调用sum函数
sum( 10, 20 );
print ("函数外是全局变量 : ", total)
- 以上实例输出结果:
函数内是局部变量 : 30
函数外是全局变量 : 0
1.7.5 函数其他使用
(1) 匿名函数
- python 使用 lambda 来创建匿名函数。
- 所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
- 语法:
- lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
- 如下实例:
#!/usr/bin/python3
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2;
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
- 以上实例输出结果:
相加后的值为 : 30
相加后的值为 : 40
1.8 Python数据类型的操作
1.8.1 Number数字
- 之前我们已经介绍了Nember类型的基本操作,下面介绍他们的操作函数(了解)
数学函数
函数 | 返回值 ( 描述 ) |
---|---|
abs(x) | 返回数字的绝对值,如abs(-10) 返回 10 |
ceil(x) | 返回数字的上入整数,如math.ceil(4.1) 返回 5 |
cmp(x, y) | 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃 。使用 使用 (x>y)-(x<y) 替换。 |
exp(x) | 返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045 |
fabs(x) | 返回数字的绝对值,如math.fabs(-10) 返回10.0 |
floor(x) | 返回数字的下舍整数,如math.floor(4.9)返回 4 |
log(x) | 如math.log(math.e)返回1.0,math.log(100,10)返回2.0 |
log10(x) | 返回以10为基数的x的对数,如math.log10(100)返回 2.0 |
max(x1, x2,…) | 返回给定参数的最大值,参数可以为序列。 |
min(x1, x2,…) | 返回给定参数的最小值,参数可以为序列。 |
modf(x) | 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。 |
pow(x, y) | x**y 运算后的值。 |
round(x [,n]) | 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。 |
sqrt(x) | 返回数字x的平方根。 |
随机数函数
函数 | 描述 |
---|---|
choice(seq) | 从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。 |
randrange ([start,] stop [,step]) | 从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1 |
random() | 随机生成下一个实数,它在[0,1)范围内。 |
seed([x]) | 改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。 |
shuffle(lst) | 将序列的所有元素随机排序 |
uniform(x, y) | 随机生成下一个实数,它在[x,y]范围内。 |
三角函数
函数 | 描述 |
---|---|
acos(x) | 返回x的反余弦弧度值。 |
asin(x) | 返回x的反正弦弧度值。 |
atan(x) | 返回x的反正切弧度值。 |
atan2(y, x) | 返回给定的 X 及 Y 坐标值的反正切值。 |
cos(x) | 返回x的弧度的余弦值。 |
hypot(x, y) | 返回欧几里德范数 sqrt(xx + yy)。 |
sin(x) | 返回的x弧度的正弦值。 |
tan(x) | 返回x弧度的正切值。 |
degrees(x) | 将弧度转换为角度,如degrees(math.pi/2) , 返回90.0 |
radians(x) | 将角度转换为弧度 |
数学常量
常量 | 描述 |
---|---|
pi | 数学常量 pi(圆周率,一般以π来表示) |
e | 数学常量 e,e即自然常数(自然常数)。 |
1.8.2 String字符串
(1) Python转义字符
转义字符 | 描述 |
---|---|
(在行尾时) | 续行符 |
\ | 反斜杠符号 |
’ | 单引号 |
" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\e | 转义 |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,yy代表的字符,例如:\o12代表换行 |
\xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
(2) Python字符串运算符
- 下表实例变量a值为字符串 “Hello”,b变量值为 “Python”:
操作符 | 描述 | 实例 |
---|---|---|
+ | 字符串连接 | a + b 输出结果: HelloPython |
* | 重复输出字符串 | a*2 输出结果:HelloHello |
[] | 通过索引获取字符串中字符 | a[1] 输出结果 e |
[ : ] | 截取字符串中的一部分 | a[1:4] 输出结果 ell |
in | 成员运算符 - 如果字符串中包含给定的字符返回 True | H in a 输出结果 1 |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True | M not in a 输出结果 1 |
r/R | 原始字符串 - 原始字符串:所有的字符串都是直接按照字面 的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母"r"(可以大 小写)以外,与普通字符串有着几乎完全相同的语法。 | print r’\n’ prints \n 和 print R’\n’ prints \n |
% | 格式字符串 | 请看下一节内容。 |
#!/usr/bin/python3
a = "Hello"
b = "Python"
print("a + b 输出结果:", a + b)
print("a * 2 输出结果:", a * 2)
print("a[1] 输出结果:", a[1])
print("a[1:4] 输出结果:", a[1:4])
if( "H" in a) :
print("H 在变量 a 中")
else :
print("H 不在变量 a 中")
if( "M" not in a) :
print("M 不在变量 a 中")
else :
print("M 在变量 a 中")
print (r'\n')
print (R'\n')
- 以上实例输出结果为:
a + b 输出结果: HelloPython
a * 2 输出结果: HelloHello
a[1] 输出结果: e
a[1:4] 输出结果: ell
H 在变量 a 中
M 不在变量 a 中
\n
\n
(3) Python字符串格式化
- Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。
- 在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。
#!/usr/bin/python3
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
# 以上实例输出结果:
# 我叫 小明 今年 10 岁!
*python字符串格式化符号:
符 号 | 描述 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
- 格式化操作符辅助指令:
符号 | 功能 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
在正数前面显示空格 | |
# | 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’) |
0 | 显示的数字前面填充’0’而不是默认的空格 |
% | ‘%%‘输出一个单一的’%’ |
(var) | 映射变量(字典参数) |
m.n. | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
- Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。
(4) Python 的字符串内建函数
序号 | 名称 | 描述 |
---|---|---|
1 | capitalize() | 将字符串的第一个字符转换为大写 |
2 | center(width, fillchar) | 返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。 |
3 | count(str, beg= 0,end=len(string)) | 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
4 | bytes.decode(encoding=“utf-8”, errors=“strict”) | Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。 |
5 | encode(encoding=‘UTF-8’,errors=‘strict’) | 以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’ |
6 | endswith(suffix, beg=0, end=len(string)) | 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. |
7 | expandtabs(tabsize=8) | 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。 |
8 | find(str, beg=0 end=len(string)) | 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1 |
9 | index(str, beg=0, end=len(string)) | 跟find()方法一样,只不过如果str不在字符串中会报一个异常. |
10 | isalnum() | 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False |
11 | isalpha() | 如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False |
12 | isdigit() | 如果字符串只包含数字则返回 True 否则返回 False… |
13 | islower() | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
14 | isnumeric() | 如果字符串中只包含数字字符,则返回 True,否则返回 False |
15 | isspace() | 如果字符串中只包含空白,则返回 True,否则返回 False. |
16 | istitle() | 如果字符串是标题化的(见 title())则返回 True,否则返回 False |
17 | isupper() | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
18 | join(seq) | 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
19 | len(string) | 返回字符串长度 |
20 | ljust(width[, fillchar]) | 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。 |
21 | lower() | 转换字符串中所有大写字符为小写. |
22 | lstrip() | 截掉字符串左边的空格或指定字符。 |
23 | maketrans() | 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 |
24 | max(str) | 返回字符串 str 中最大的字母。 |
25 | min(str) | 返回字符串 str 中最小的字母。 |
26 | replace(old, new [, max]) | 把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次。 |
27 | rfind(str, beg=0,end=len(string)) | 类似于 find()函数,不过是从右边开始查找. |
28 | rindex( str, beg=0, end=len(string)) | 类似于 index(),不过是从右边开始. |
29 | rjust(width,[, fillchar]) | 返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串 |
30 | rstrip() | 删除字符串字符串末尾的空格. |
31 | split(str="", num=string.count(str)) | num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num 个子字符串 |
32 | splitlines([keepends]) | 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。 |
33 | startswith(str, beg=0,end=len(string)) | 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。 |
34 | strip([chars]) | 在字符串上执行 lstrip()和 rstrip() |
35 | swapcase() | 将字符串中大写转换为小写,小写转换为大写 |
36 | title() | 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) |
37 | translate(table, deletechars="") | 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中 |
38 | upper() | 转换字符串中的小写字母为大写 |
39 | zfill (width) | 返回长度为 width 的字符串,原字符串右对齐,前面填充0 |
40 | isdecimal() | 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。 |
1.8.3 List列表
- 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
- 列表操作实例:
#!/usr/bin/python3
# 定义
list0 = [] # 创建一个空列表 或者 变量 = list()
list1 = ['Google', 'Python', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
#输出
print ("list1[0]: ", list1[0]) # Google
print ("list2[1:5]: ", list2[1:5]) # [2, 3, 4, 5]
#更新其中的值
print ("第三个元素为 : ", list[2]) # 2000
list[2] = 2001
print ("更新后的第三个元素为 : ", list[2]) # 2001
#删除其中一个元素
del list[2]
print ("删除第三个元素 : ", list) # ['Google', 'Python', 2000]
(1) 列表的遍历操作:
1.使用for...in 遍历列表
for 变量 in 列表:
使用变量
2.使用while循环遍历列表
i = 0
while i<len(列表):
使用列表中的元素(列表[i])
i += 1
3.同等长度二级列表的遍历
列表 = [[值1,值2],[值1,值2],....]
for 变量1,变量2 in 列表:
使用变量1和变量2
注意:变量1取二级列表中的第一个值,变量2取第二个值
4.非同等长度的二级列表的遍历
列表 = [[值1,值2],[值1,值2,值3],[值]...]
for 变量1 in 列表:
for 变量2 in 变量1:
使用变量2(变量2是二级列表中的每个值)
(2) Python列表脚本操作符
- 列表对 + 和 的操作符与字符串相似。+ 号用于组合列表, 号用于重复列表。
Python 表达式 | 结果 | 描述 |
---|---|---|
len([1, 2, 3]) | 3 | 长度 |
[1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 组合 |
[‘Hi!’] * 4 | [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] | 重复 |
3 in [1, 2, 3] | True | 元素是否存在于列表中 |
for x in [1, 2, 3]: print(x, end=" ") | 1 2 3 | 迭代 |
(3) Python列表截取与拼接
- Python的列表截取与字符串操作类型,如下所示:L=[‘Google’, ‘Python’, ‘Taobao’]
Python | 表达式 结果 | 描述 |
---|---|---|
L[2] | ‘Taobao’ | 读取第三个元素 |
L[-2] | ‘Python’ | 从右侧开始读取倒数第二个元素: count from the right |
L[1:] | [‘Python’, ‘Taobao’] | 输出从第二个元素开始后的所有元素 |
- 使用嵌套列表即在列表里创建其它列表,例如:
>>>a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'
(4) Python列表函数&方法
- Python包含以下函数:
序号 | 函数名称 | 说明 |
---|---|---|
1 | len(list) | 列表元素个数 |
2 | max(list) | 返回列表元素最大值 |
3 | min(list) | 返回列表元素最小值 |
4 | list(seq) | 将元组转换为列表 |
- Python包含以下方法:
序号 | 方法名称 | 说明 |
---|---|---|
1 | list.append(obj) | 在列表末尾添加新的对象 |
2 | list.count(obj) | 统计某个元素在列表中出现的次数 |
3 | list.extend(seq) | 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
4 | list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 |
5 | list.insert(index, obj) | 将对象插入列表 |
6 | list.pop(obj=list[-1]) | 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
7 | list.remove(obj) | 移除列表中某个值的第一个匹配项 |
8 | list.reverse() | 反向列表中元素 |
9 | list.sort([func]) | 对原列表进行排序 |
10 | list.clear() | 清空列表 |
11 | list.copy() | 复制列表 |
1.8.4 Tuple元组
- Python 的元组与列表类似,不同之处在于元组的元素不能修改。
- 元组使用小括号,列表使用方括号。
- 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
# 定义元组的方式:
tup0 = () #定义一个空元组 或者 变量 = tuple()
tup1 = ('Google', 'Python', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d"
# 输出元组:
print ("tup1[0]: ", tup1[0]) # tup1[0]: Google
print ("tup2[1:5]: ", tup2[1:5]) # tup2[1:5]: (2, 3, 4, 5)
# 注意下面这种定义不加逗号,类型为整型
tup4 = (50)
print(type(tup4)) # <class 'int'>
# 正确定义方式加上逗号,类型为元组
tup5 = (50,)
print(type(tup5)) # <class 'tuple'>
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
#元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组
del tup0;
(1) 元组运算符
- 与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。
Python 表达式 | 结果 | 描述 |
---|---|---|
len((1, 2, 3)) | 3 | 长度 |
(1, 2, 3) + (4, 5, 6) | (1, 2, 3, 4, 5, 6) | 组合 |
(‘Hi!’) * 4 | (‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’) | 重复 |
3 in (1, 2, 3) | True | 元素是否存在于元组中 |
for x in (1, 2, 3): print(x, end=" ") | 1 2 3 | 迭代 |
(2)元组索引,截取
- 因为元组也是一个序列,所以我们可以访问元组中的指定位置的元素,也可以截取索引中的一段元素
- 如下所示:L=(‘Google’, ‘Python’, ‘Taobao’)
Python | 表达式 结果 | 描述 |
---|---|---|
L[2] | ‘Taobao’ | 读取第三个元素 |
L[-2] | ‘Python’ | 从右侧开始读取倒数第二个元素: count from the right |
L[1:] | (‘Python’, ‘Taobao’) | 输出从第二个元素开始后的所有元素 |
(3) 元组内置函数
- Python元组包含了以下内置函数:
序号 | 函数名称 | 说明 |
---|---|---|
1 | len(tuple) | 元组元素个数 |
2 | max(tuple) | 返回元组元素最大值 |
3 | min(tuple) | 返回元组元素最小值 |
4 | tuple(seq) | 将元组转换为元组 |
list1= ['Google', 'Taobao', 'Runoob', 'Baidu']
tuple1=tuple(list1)
print(tuple1)
#('Google', 'Taobao', 'Runoob', 'Baidu')
1.8.5 Sets集合
- 集合(set)是一个无序不重复元素的序列。
- 基本功能是进行成员关系测试和删除重复元素。
- 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
# 集合的定义
set1 = set() #定义一个空的集合
set2 = {1,2,3}
# 增加一个元素
set1.add(5)
#增加多个:
set1.update([5,6,7,8])
#删除某个值
set1.remove(1)
#查:无法通过下标索引
#改:不可变类型无法修改元素
a={10,20,30}
b={20,50}
print(a - b) # a和b的差集
print(a | b) # a和b的并集
print(a & b) # a和b的交集
print(a ^ b) # a和b中不同时存在的元素
(1) 集合的遍历
1.普通序列的遍历
for 变量 in 集合:
使用变量
2.多级集合
集合 = {(值,值..),(值,值..)。。。}
for 变量1,变量2 in 集合:
使用变量1和变量2
(2) 集合的序列函数
- len() 计算集合的长度
- max() 获取集合中的最大值
- min() 获取集合中的最小值
- set() 创建空集合或者将其他数据转换为集合
(3) 集合中的方法
- add – 增加集合元素
name = {'d', 's'}
name.add('d')
name
返回结果:{'d', 's'}
name.add('sd')
name
返回结果:{'sd', 'd', 's'}
- update–更新已有集合
name = {'sd', 'd', 's'}
name.update('df')
name
返回结果:{'sd', 'd', 'f', 's'}
- remove–移除指定集合元素
name = {'sd','d','s'}
name.remove('s')
返回结果:name
{'sd', 'd'}
- discard–移除元素
name = {'sd', 'd', 's'}
name.discard('s')
返回结果:name
{'sd', 'd'}
# remove移除非成员值会报错,discard移除非成员值,啥也不错!
- clear–清空集合元素
name = {'d', 's'}
name.clear()
name
返回结果:{}
- copy–浅拷贝
name = {'sd', 'd', 's'}
li = name.copy()
返回结果:li
{'sd', 'd', 's'}
- difference – 求差集
name.difference(li)
set()
>>> name.difference()
{'sd', 'd', 's'}
- union–并集,创建新的对象
name = {'sd', 'd', 's'}
li = {'s', 'd','h'}
name.union(li)
返回结果:{'h', 's', 'd', 'sd'}
- difference_update—删除当前set中的所有包含在 new set 里的元素
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.difference_update(li)
name
返回结果:{'sd'}
- intersection–取交集,建立新的set集合
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.intersection(li)
返回结果:{'d', 's'}
- intersection_update–取交集,更新原来的set集合
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.intersection_update(li)
返回结果:{'d', 's'}
- isdisjoint–判断没有交集,返回True,否则,返回False
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.isdisjoint(li)
- issubset–判断是否是子集
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.issubset(li) #判断name是不是li的子集
返回结果:False
li.issubset(name) #判断li是不是name的子集
返回结果:True
- issuperset–判断是否是父集
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.issuperset(li) #判断name是不是li的父集
返回结果:True
li.issuperset(name) #判断li是不是name的父集
返回结果:False
- pop–移除集合元素
name = {'sd', 'd', 's'}
name.pop()
返回结果:'sd' #同一个集合,删除集合元素的顺序固定
se1 = {'a','s','sb'}
se1.pop()
返回结果:'sb'
- symmetric_difference–去两个集合的差集,建立新的set集合对象
name = {'sd', 'd', 's'}
li = {'s', 'd'}
name.symmetric_difference(li)
返回结果:{'sd'}
- symmetric_difference_update–去两个集合的差集,更新原来的集合对象
name = {'sd', 'd', 's'}
li = {'s', 'd'}
name.symmetric_difference_update(li)
返回结果:{'sd'}
1.8.6 Dictionary字典
- 字典是另一种可变容器模型,且可存储任意类型对象。
- 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
- 键必须是唯一的,但值则不必。
(1) 创建字典
1.创建空字典
变量 = {} 或者 变量 = dict()
2.创建多个元素的字典:
方法1:
变量 = {键:值,键:值....}
方法2:
变量 = dict({键:值,键:值....})
方法3:
变量 = dict(键=值,键=值...)
注意:该方式键作为形参名使用不可以添加引号,必须符合变量规则
方法4:
变量 = dict([(键,值),(键,值)...])
变量 = dict([[键,值],[键,值]...])
变量 = dict(((键,值),(键,值)...))
方法5:
变量 = dict(zip((键,键...),(值,值...)))
(2) 字典的基本操作
访问字典的元素:
变量[键]
添加字典的元素
变量[新键] = 值
修改字典元素
变量[键] = 新值
删除字典元素
del 变量[键]
- 案例:
#!/usr/bin/python3
# 定义一个字典
dict = {'Name': 'Python', 'Age': 17, 'Class': 'First'}
# 输出子典中的信息
print ("dict['Name']: ", dict['Name']) #Python
print ("dict['Age']: ", dict['Age']) #17
# 输出错误信息:KeyError: 'Alice'
#print ("dict['Alice']: ", dict['Alice'])
# 修改和添加内容
dict['Age'] = 18; # 更新 Age
dict['School'] = "云课堂" # 添加信息
# 删除信息
del dict['Name'] # 删除键 'Name'一个元素值
dict.clear() # 清空字典
del dict # 删除字典
字典的遍历:
1.键的遍历
for 变量i in 字典:
使用i遍历所有的键,有键就可以通过变量访问其值
2.键值遍历
for 变量i,变量j in 字典.items():
使用变量i遍历所有键,通过变量j遍历所有值
字典内涵/字典推导式:
1.普通的字典内涵
变量= {key:value for key,value in 字典.items()}
2.带有判断条件的字典内涵
变量= {key:value for key,value in 字典.items() if 条件表达式}
3,多个循环的字典内涵
变量 = {i+x:j+y for i,j in 字典1.items for x,y in 字典2.items()}
4.带有判断条件的多个循环的字典内涵
变量 = {i+x:j+y for i,j in 字典1.items for x,y in 字典2.items() if 条件表达式}
字典内置函数&方法:
- Python字典包含了以下内置函数:
序号 | 函数名称 | 描述 | 实例 |
---|---|---|---|
1 | len(dict) | 计算字典元素个数, 即键的总数。 | >>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> len(dict) 3 |
2 | str(dict) | 输出字典, 以可打印的字符串表示。 | >>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> str(dict) “{‘Name’: ‘py’, ‘Class’: ‘First’, ‘Age’: 7}” |
3 | type(variable) | 返回输入的变量类型, 如果变量是字典 就返回字典类型。 | >>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> type(dict) <class ‘dict’> |
- Python字典包含了以下内置方法:
序号 | 方法名称 | 描述 |
---|---|---|
1 | radiansdict.clear() | 删除字典内所有元素 |
2 | radiansdict.copy() | 返回一个字典的浅复制 |
3 | radiansdict.fromkeys() | 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值 |
4 | radiansdict.get(key, default=None) | 返回指定键的值,如果值不在字典中返回default值 |
5 | key in dict | 如果键在字典dict里返回true,否则返回false |
6 | radiansdict.items() | 以列表返回可遍历的(键, 值) 元组数组 |
7 | radiansdict.keys() | 以列表返回一个字典所有的键 |
8 | radiansdict.setdefault(key, default=None) | 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default |
9 | radiansdict.update(dict2) | 把字典dict2的键/值对更新到dict里 |
10 | radiansdict.values() | 以列表返回字典中的所有值 |
11 | pop(key[,default]) | 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。 |
12 | popitem() | 随机返回并删除字典中的一对键和值(一般删除末尾对)。 |
1.9 Python文件操作
- 文件操作主要讲解以下内容:
- 1.文件本身的操作(python内置)
- 2.系统中文件和文件夹的操作(os和shutil模块当中)
- 3.系统路径相关操作(os模块中的子模块 os.path)
(1) 文件的基本操作
- open() 打开或者创建一个文件
格式:open('文件路径','打开模式')
返回值:文件io对象
打开模式一共N种:
w模式 写模式write 文件不存在时会创建文件,如果文件已存在则会清空文件
r模式 读模式read 文件不存在就报错,存在则准备读取文件
a模式 追加模式 append 文件不存在则新建,文件存在则在文件末尾追加内容
x模式 抑或模式 xor 文件存在则报错,文件 不存在则新建文件
b模式 二进制模式 binary 辅助模式不能单独使用
+模式 增强模式plus 也是辅助模式不能单独使用
- 以上模式可以互相组合:wrax不可以互相组合:
模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
- close() 关闭文件
格式:文件io对象.close()
返回值:None
- 示例如下:
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
# 关闭这个文件
f.close()
读写函数:
- read() 读取文件
格式:文件io对象.read()
返回值:整个文件的字符
格式:文件io对象.read(字符长度)
返回值:指定长度的字符
f = open('test.txt', 'r')
content = f.read(5)
print(content)
print("-"*30)
content = f.read()
print(content)
f.close()
- readline() 读取一行文件
格式:文件io对象.readline()
返回值:一行内容的字符串
格式:文件io对象.readline(字符长度)
返回值:一行内容的字符串
注意:字符长度<当前行内内容,则读取指定长度的字符串,并且下次再读取还是在
这个一行中获取没有读取的内容。字符长度>=当前行内容,直接读取当前行
#coding=utf-8
f = open('test.txt', 'r')
content = f.readline()
print("1:%s"%content)
content = f.readline()
print("2:%s"%content)
f.close()
- readlines() 将文件中的内容读取到序列当中。
格式:文件io对象.readlines()
返回值:列表
格式:文件io对象.readlines(字符长度)
返回值:列表
注意:读取的行数由字符长度决定,如果字符长度读取了N行后,还有指定长度的字符
没有读取,则直接读取下一行进来
#coding=utf-8
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))
i=1
for temp in content:
print("%d:%s"%(i, temp))
i+=1
f.close()
- write() 写入文件
格式:文件io对象.write(字符串)
返回值:写入字符串的长度
- writelines() 将序列写入文件中
格式:文件io对象.writelines(序列)
返回值:None
- truncate() 字符串截取操作
格式:文件io对象.truncate(字节长度)
返回值:截取的字节长度
(2) OS模块
- OS – 操作系统的简称
- os模块就是对操作系统进行操作
- 使用该模块必须先导入模块:
import os
os模块中的函数:
序号 | 函数名称 | 描述 | 格式 |
---|---|---|---|
1 | getcwd() | 获取当前的工作目录 | 格式:os.getcwd() 返回值:路径字符串 |
2 | chdir() | 修改当前工作目录 | 格式:os.chdir() 返回值:None |
3 | listdir() | 获取指定文件夹中的 所有文件和文件夹组成的列表 | 格式:os.listdir(目录路径) 返回值:目录中内容名称的列表 |
4 | mkdir() | 创建一个目录/文件夹 | 格式:os.mkdir(目录路径) 返回值:None |
5 | makedirs() | 递归创建文件夹 | 格式:os.makedirs(路径) |
6 | rmdir() | 移除一个目录(必须是空目录) | 格式:os.rmdir(目录路径) 返回值:None |
7 | removedirs() | 递归删除文件夹 | 格式:os.removedirs(目录路径) 返回值:None 注意最底层目录必须为空 |
8 | rename() | 修改文件和文件夹的名称 | 格式:os.rename(源文件或文件夹,目标文件或文件夹) 返回值:None |
9 | stat() | 获取文件的相关 信息 | 格式:os.stat(文件路径) 返回值:包含文件信息的元组 |
10 | system() | 执行系统命令 | 格式:os.system() 返回值:整型 慎用! 玩意来个rm -rf 你就爽了! |
11 | getenv() | 获取系统环境变量 | 格式:os.getenv(获取的环境变量名称) 返回值:字符串 |
12 | putenv() | 设置系统环境变量 | 格式:os.putenv(‘环境变量名称’,值) 返回值:无 注意:无法正常的getenv检测到。 |
13 | exit() | 推出当前执行命令,直接关闭当前操作 | 格式:exit() 返回值:无 |
当前os模块的值:
序号 | 函数名称 | 描述 |
---|---|---|
1 | curdir | os.curdir 获取当前路径 都是. |
2 | pardir | os.pardir 获取上层目录路径 都是… |
3 | path | os.path os中的一个子模块,操作非常多 |
4 | name | os.name 当前系统的内核名称 win->nt linux/unix->posix |
5 | sep | os.sep 获取当前系统的路径分割符号 window -> \ linux/unix -> / |
6 | extsep | os.extsep 获取当前系统中文件名和后缀之间的分割符号,所有系统都是. |
7 | linesep | os.linesep 获取当前系统的换行符号 window -> \r\n linux/unix -> \n |
os.environ模块
- os.environ 可以直接获取所有环境变量的信息组成的字典,如果希望更改环境变量,并且可以查询得到,就需要对os.environ进行操作
- 该模块的所有方法均是字典的方法,可以通过字典的os.environ的结果进行操作。
- 注意:无论使用os.getenv,putenv 还是使用os.environ进行环境变量的操作,都是只对当前脚本,临时设置而已,无法直接更新或者操作系统的环境变量设置。
os.path模块
- os.path是os模块中的子模块,包含很多和路径相关的操作
- 函数部分:
序号 | 函数名称 | 描述 | 格式 |
---|---|---|---|
1 | abspath() | 将一个相对路径转化为绝对路径 | 格式:os.path.abspath(相对路径) 返回值:绝对路径字符串 |
2 | basename() | 获取路径中的文件夹或者文件名称 (只要路径的最后一部分) | 格式:os.path.basename(路径) 返回值:路径的最后一部分(可能是文件名也可能是文件夹名) |
3 | dirname() | 获取路径中的路径部分(出去最后一部分) | 格式:os.path.dirname(路径) 返回值:路径中除了最后一部分的内容字符串 |
4 | join() | 将2个路径合成一个路径 | 格式:os.path.join(路径1,路径2) 返回值:合并之后的路径 |
5 | split() | 将一个路径切割成文件夹和文件名部分 | 格式:os.path.split(路径) 返回值:元组 |
6 | splitext() | 将一个文件名切成名字和后缀两个部分 | 格式:os.path.splitext(文件名称) 返回值:元组 (名称,后缀) |
7 | getsize() | 获取一个文件的大小 | 格式:os.path.getsize(路径) 返回值:整数 |
8 | isfile() | 检测一个路径是否是一个文件 | 格式:os.path.isfile(路径) 返回值:布尔值 |
9 | isdir() | 检测一个路径是否是一个文件夹 | 格式:os.path.isdir(路径) 返回值:布尔值 |
10 | getctime() | 获取文件的创建时间! get create time | 格式:os.path.getctime(文件路径) 返回值:时间戳浮点数 |
11 | getmtime() | 获取文件的修改时间! get modify time | 格式:os.path.getmtime(文件路径) 返回值:时间戳浮点数 |
12 | getatime() | 获取文件的访问时间! get active time | 格式:os.path.getatime(文件路径) 返回值:时间戳浮点数 |
13 | exists() | 检测指定的路径是否存在 | 格式:os.path.exists(路径) 返回值:布尔值 |
14 | isabs() | 检测一个路径是否是绝对路径 | 格式:os.path.isabs(路径) 返回值:布尔值 |
15 | islink() | 检测一个路径是否是链接 | 格式:os.path.islink(路径) 返回值:布尔值 |
16 | samefile() | 检测2个路径是否指向同一个文件 | 格式:os.path.samefile(路径1,路径2) 返回值:布尔值 |
1.10 综合案例实战
使用python学习内容实现一个在线学员信息管理操作
- 数据临时存放在变量列表中
- 实现学生信息的添加,删除和查询操作。
初识界面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MTNUq2tu-1603700619111)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070330.png)]
添加学员信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BGasgXuW-1603700619112)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070431.png)]
浏览学员信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DQgAdgK7-1603700619113)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070443.png)]
删除学员信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPaDpTwF-1603700619114)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070520.png)]
退出操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVzY6IGP-1603700619115)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070540.png)]
参考程序代码如下:
# 学员信息在线管理
# 定义一个用于存放学员信息的列表变量
stulist=[
{'name':'zhangsan','age':20,'classid':'python02'},
{'name':'lisi','age':22,'classid':'python03'},
{'name':'wangwu','age':25,'classid':'python04'}]
#定义一个学生信息的输出函数
def showStu(stulist):
'''
学生信息的输出函数
'''
if len(stulist)==0:
print("========== 没有学员信息可以输出!=============")
return
print("|{0:<5}| {1:<10}| {2:<5}| {3:<10}|".format("sid","name","age","classid"))
print("-"*40)
for i in range(len(stulist)):
print("|{0:<5}| {1:<10}| {2:<5}| {3:<10}|".format(i+1,stulist[i]['name'],stulist[i]['age'],stulist[i]['classid']))
while True:
# 输出初始界面
print("="*12,"学员管理系统","="*14)
print("{0:1} {1:13} {2:15}".format(" ","1. 查看学员信息","2. 添加学员信息"))
print("{0:1} {1:13} {2:15}".format(" ","3. 删除学员信息","4. 退出系统"))
print("="*40)
key = input("请输入对应的选择:")
# 根据键盘值,判断并执行对应的操作
if key == "1":
print("="*12,"学员信息浏览","="*14)
showStu(stulist)
input("按回车键继续:")
elif key == "2":
print("="*12,"学员信息添加","="*14)
stu={}
stu['name']=input("请输入要添加的姓名:")
stu['age']=input("请输入要添加的年龄:")
stu['classid']=input("请输入要添加的班级号:")
stulist.append(stu)
showStu(stulist)
input("按回车键继续:")
elif key == "3":
print("="*12,"学员信息删除","="*14)
showStu(stulist)
sid = input("请输入你要删除的信息id号:")
del stulist[int(sid)-1]
showStu(stulist)
input("按回车键继续:")
elif key == "4":
print("="*12,"再见","="*14)
break
else:
print("======== 无效的键盘输入! ==========")
二、Python基础进阶
1.11 Python面向对象编程
- Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.
面向对象技术简介
类(Class)
: 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。类变量
:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。数据成员
:类变量或者实例变量用于处理类及其实例对象的相关的数据。方法重写
:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。实例变量
:定义在方法中的变量,只作用于当前实例的类。继承
:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。实例化
:创建一个类的实例,类的具体对象。方法
:类中定义的函数。对象
:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
1.11.2 类和对象
3
class ClassName:
<statement-1>
.
.
.
<statement-N>
- 实例:
#!/usr/bin/python3
# 类的定义
class MyClass:
i = 12345
def f(self):
return 'hello world'
# 实例化类
x = MyClass()
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())
# 结果:
# MyClass 类的属性 i 为: 12345
# MyClass 类的方法 f 输出为: hello world
1.11.3 构造函数
- 很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 init() 的特殊方法(构造方法),像下面这样:
def __init__(self):
self.data = []
- 类定义了 init() 方法的话,类的实例化操作会自动调用 init() 方法。所以在下例中,可以这样创建一个新的实例:
x = MyClass()
- 当然, init() 方法可以有参数,参数通过 init() 传递到类的实例化操作上。例如:
#!/usr/bin/python3
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
self代表类的实例,而非类
- 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
- 以上实例执行结果为:
<__main__.Test instance at 0x100771878>
__main__.Test
- 从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。
- self 不是 python 关键字,我们可以换成其他变量名
1.11.4 类的属性和方法
类的方法:
- 在类地内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
#!/usr/bin/python3
#类定义
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('runoob',10,30)
p.speak()
- 执行以上程序输出结果为:
runoob 说: 我 10 岁。
类属性与方法:
-
类的私有属性
- **private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.**private_attrs。
-
类的方法
- 在类地内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
- self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
-
类的私有方法
- **private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用。self.**private_methods。
1.11.5 继承与重载
- Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。派生类的定义如下所示:
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
#!/usr/bin/python3
#类定义
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 年级
多继承:
- Python同样有限的支持多继承形式。多继承的类定义形如下例:
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
- 需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
#!/usr/bin/python3
#类定义
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 speaker():
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(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("Tim",25,80,4,"Python")
test.speak() #方法名同,默认调用的是在括号中排前地父类的方法
# 执行以上程序输出结果为:
# 我叫 Tim,我是一个演说家,我演讲的主题是 Python
方法重写:
- 如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:
#!/usr/bin/python3
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
# 执行以上程序输出结果为:
# 调用子类方法
1.11.6 其他
- 类的专有方法:
__init__
: 构造函数,在生成对象时调用__del__
: 析构函数,释放对象时使用__repr__
: 打印,转换__setitem__
: 按照索引赋值__getitem__
: 按照索引获取值__len__
: 获得长度__cmp__
: 比较运算__call__
: 函数调用__add__
: 加运算__sub__
: 减运算__mul__
: 乘运算__div__
: 除运算__mod__
: 求余运算__pow__
: 乘方
- 运算符重载
- Python同样支持运算符重载,我们可以对类的专有方法进行重载,实例如下:
#!/usr/bin/python3
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
# 以上代码执行结果如下所示:
# Vector(7,8)
1.12 Python中的异常处理
1.12.1 异常介绍
- 即便Python程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
- 大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
- 异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。
- Python的一些內建异常:
Exception 常规错误的基类
AttributeError 对象没有这个属性
IOError 输入/输出操作失败
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
NameError 未声明/初始化对象 (没有属性)
SyntaxError Python 语法错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
ZeroDivisionError 除(或取模)零 (所有数据类型)
- 更多可以参考:http://blog.csdn.net/gavin_john/article/details/50738323
附加:Python—内建异常体系结构
Python异常体系结构如下图:
常见的异常如下表所示:
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
# 注意:
BaseException是异常的顶级类。但是这个类不能当作是由用户定义的类直接继承的,而是要继承Exception。Exception类是与应用相关的异常的顶层根超类,除了系统退出事件类之外(SystemExit、KeyboardInterrupt和GeneratorExit),几乎所有的用户定义的类都应该继承自这个类,而不是BaseException
1.12.2 异常处理
- 没有异常处理的:特点是出现异常会终止程序执行。
print("start.....")
x = int(input("Please enter a number: "))
print("number:",x)
print("ok....")
print("end.....")
- 使用了有异常处理的代码,程序会执行到最后
print("start.....")
try:
x = int(input("Please enter a number: "))
print("number:",x)
print("ok....")
except ValueError:
print("Oops! That was no valid number. Try again")
print("end.....")
- try语句按照如下方式工作;
- 首先,执行try子句(在关键字try和关键字except之间的语句)
- 如果没有异常发生,忽略except子句,try子句执行后结束。
- 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
- 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
- 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
- 处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
- 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
except (RuntimeError, TypeError, NameError):
pass
- 最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
异常处理实例
- 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行
- 最后一个except子句可以忽略异常的名称,它将被当作通配符使用
print("start.....")
try:
x = int(input("Please enter a number: "))
print("number:",x)
print(100/x)
print("ok....")
except ValueError:
print("非纯数字错误!")
except ZeroDivisionError:
print("不可以为零错误!")
except:
print("可选的未知错误!")
print("end.....")
- 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
print("start.....")
try:
x = int(input("Please enter a number: "))
print("number:",x)
print(100/x)
print("ok....")
except (ValueError,ZeroDivisionError):
print("非纯数字或不可以为零错误!")
except:
print("可选的未知错误!")
raise #重新抛出这个异常
print("end.....")
1.12.3 抛出异常(自行抛出异常)
- Python 使用 raise 语句抛出一个指定的异常。例如:
>>> raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: HiThere
- raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
- 如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
>>> try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
1.13 魔术方法、属性和迭代器
1.13.1 魔术方法:
- 在Python中的面向对象中有很多魔术方法如:
__init__: 构造函数,在生成对象时调用
__del__: 析构函数,释放对象时使用
__str__: 使用print(对象)或者str(对象)的时候触发
__repr__: 在使用repr(对象)的时候触发
__setitem__ : 按照索引赋值:每当属性被赋值的时候都会调用该方法:self.__dict__[name] = value
__getitem__: 按照索引获取值:当访问不存在的属性时会调用该方法
_delitem__(self,name): 当删除属性时调用该方法
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__div__: 除运算
__mod__: 求余运算
__pow__: 乘方
...
- 注意:
__setitem__
: 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环 __str__
函数用于处理打印实例本身的时候的输出内容。如果没有覆写该函数,则默认输出一个对象名称和内存地址。
class Stu:
name= '张三'
age = 20
def __str__(self):
return "姓名:%s; 年龄:%d"%(self.name,self.age)
s = Stu()
print(s)
- 析构魔术方法,当对象从内存被释放前调用的方法,目的是做一些释放销毁工作。
class Demo:
def __init__(self,x):
self.x = x;
print("create demo...",self.x)
def __del__(self):
print("del demo....",self.x)
d1 = Demo(1)
d2 = Demo(2)
d3 = Demo(3)
del d3
__add__
: 加运算
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
# 以上代码执行结果如下所示:
# Vector(7,8)
1.13.2 属性和方法
property() 函数的作用是在新式类中返回属性值
* ```class property([fget[, fset[, fdel[, doc]]]])```
* fget -- 获取属性值的函数
* fset -- 设置属性值的函数(可选)
* fdel -- 删除属性值函数(可选)
* doc -- 属性描述信息(可选)
# 定义一个矩形类,假象有一个size特性访问器方法
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def setSize(self,size):
self.width,self.height=size
def getSize(self):
return self.width,self.height
#测试
rt = Rectangle()
#rt.width=100
#rt.height=50
rt.setSize((200,100)) #赋值
print(rt.getSize()) #(200,100)
- 对应上面的实例,
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def setSize(self,size):
self.width,self.height=size
def getSize(self):
return self.width,self.height
size = property(getSize,setSize,fdel)
rt = Rectangle()
#rt.width=100
#rt.height=50
rt.setSize((200,100))
print(rt.getSize())
rt.size = 10,5
print(rt.size)
静态方法和类成员方法(区别是有无带参数)
- 使用staticmethod()和classmethod()函数 或使用@staticmethod和@classmethod装饰器
class MyClass1:
def smeth():
print('这是一个静态方法')
smeth = staticmethod(smeth)
def cmeth(cls):
print("这是一个类成员方法",cls)
cmeth = classmethod(cmeth)
MyClass1.smeth()
MyClass1.cmeth()
#或使用使用@staticmethod和@classmethod装饰器
class MyClass2:
@staticmethod
def smeth():
print('这是一个静态方法')
@classmethod
def cmeth(cls):
print("这是一个类成员方法",cls)
MyClass2.smeth()
MyClass2.cmeth()
- 使用hasattr()函数判读对象中是否存在指定的非私有属性和方法:
class B:
name="zhangsan"
__age=20
def bb(self):
print("bbbbb")
def __cc(self):
print("cccc")
b = B()
print(hasattr(b,"name")) #True
print(hasattr(b,"__age")) #False
print(hasattr(b,"sex")) #False
print(hasattr(b,"bb")) #True
print(hasattr(b,"__cc")) #False
print()
1.13.3 迭代器:
- 指定数据创建迭代器(使用iter()和next() )
x = [1, 2, 3] #定义一个列表:<class 'list'>
y = iter(x) #创建一个可迭代对象:<class 'list_iterator'>
#print(next(y)) # 1
#print(next(y)) # 2
#print(next(y)) # 3
#print(next(y)) # 迭代结束会后返回异常StopIteration错误
for i in y:
print(i,end=" ")
print()
# 1 2 3
- 迭代对象:定义魔术方法:
__next__()
和__iter__()
class A:
def __init__(self):
self.x=0
def __next__(self):
self.x += 1
if self.x>10:
raise StopIteration
return self.x
def __iter__(self):
return self
a = A()
print(list(a))
#for i in a:
# print(i)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1.14 Python模块实战
1.14.1 什么是Python模块
- Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
- 模块让你能够有逻辑地组织你的 Python 代码段。
- 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
- 模块能定义函数,类和变量,模块里也能包含可执行的代码。
1.14.2 Python模块的导入
(1) import 语句
- 想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:
import module1[, module2[,... moduleN]
import random
random.choice([0,1,2,3,4,5]) #随机从列表中获取一个
random.randrange(1,10) #1~9随机一个
import time
# 格式化成2016-03-20 11:45:39形式
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
(2) from…import 语句
- Python的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:
from modname import name1[, name2[, ... nameN]]
from time import strftime,localtime
# 格式化成2016-03-20 11:45:39形式
print (strftime("%Y-%m-%d %H:%M:%S", localtime()))
1.14.3 第三方模块的安装
- 使用pip命令安装
- pip install 模块名
- pip uninstall 模块名
- pip freeze --查看都安装了哪些模块名
- whl下载安装的方式
- 网址: https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载
- 安装:pip install 文件包名
- 直接复制的方式
- anaconda
1.14.4 自定义Python模块
- 在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
- 目录只有包含一个叫做
__init__.py
的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做string
)不小心的影响搜索路径中的有效模块。 - 最简单的情况,放一个空的 :
file:__init__.py
就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的)__all__
变量赋值。
1.15 MySQL数据库基础
1.15.1 MySQL简介
- Mysql是最流行的RDBMS(Relational Database Management System:关系数据库管理系统),特别是在WEB应用方面。
- 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,
- 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据。
- 所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
- RDBMS即关系数据库管理系统(Relational Database Management System)的特点:
- 1.数据以表格的形式出现
- 2.每行为各种记录名称
- 3.每列为记录名称所对应的数据域
- 4.许多的行和列组成一张表单
- 5.若干的表单组成database
- 在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语:
数据库: 数据库是一些关联表的集合。.
数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
列: 一列(数据元素) 包含了相同的数据, 例如邮政编码的数据。
行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
外键:外键用于关联两个表。
复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
SQL:
- SQL: 结构化查询语言(Structured Query Language)简称SQL,是最重要的关系数据库操作语言.
- 有上百种数据库产品都支持SQL,如:MySQL、DB2、ORACLE、INGRES、SYBASE、SQLSERVER…
- 结构化查询语言包含6个部分:
1. 数据查询语言(DQL:Data Query Language):SELECT
2. 数据操作语言(DML:Data Manipulation Language):INSERT,UPDATE和DELETE
3. 事务处理语言(TPL):BEGIN TRANSACTION,COMMIT和ROLLBACK
4. 数据控制语言(DCL):GRANT(授权)或REVOKE(回收权限)
5. 数据定义语言(DDL):CREATE、ALTER和DROP
6. 指针控制语言(CCL):DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用于对一个或多个表单独行的操作
- 在本节中,会让大家快速掌握Mysql的基本知识,并轻松使用Mysql数据库。
mysql数据库的安装:
- 网址:https://www.mysql.com/downloads/ 下载,但是已经是商业版了
- 可下载 MariaDB 开源的 https://downloads.mariadb.org
- 建议Window上可以安装一个集成环境如:XAMPP:https://www.apachefriends.org/zh_cn/download.html
- Ubuntu系统安装:sudo apt-get install mysql-server mysql-client
- 服务的启动和停止
- 配置文件:windows下是:my.ini Linux下:mysqld.conf
连接数据库:
mysql -h 主机名 -u 用户名 -p密码 库名
C:\>mysql --采用匿名账号和密码登陆本机服务
C:\>mysql -h localhost -u root -proot --采用root账号和root密码登陆本机服务
C:\>mysql -u root -p --推荐方式默认登陆本机
Enter password: ****
C:\>mysql -u root -p mydb --直接进入mydb数据库的方式登陆
SQL语句中的快捷键
\G 格式化输出(文本式,竖立显示)
\s 查看服务器端信息
\c 结束命令输入操作
\q 退出当前sql命令行模式
\h 查看帮助
1.15.2. SQL的基本操作
数据库操作:
mysql> show databases; --查看当前用户下的所有数据库
mysql> create database [if not exists] 数据库名; --创建数据库
mysql> use test; --选择进入test数据库
mysql> show create database 数据库名\G --查看建数据库语句
mysql> select database(); --查看当前所在的数据库位置
mysql> drop database [if exists] 数据库名; --删除一个数据库
数据表操作:
mysql> show tables; --查看当前库下的所有表格
mysql> desc tb1; --查看tb1的表结构。
mysql> show create table 表名\G --查看表的建表语句。
mysql> create table demo( --创建demo表格
-> name varchar(16) not null,
-> age int,
-> sex enum('w','m') not null default 'm');
Query OK, 0 rows affected (0.05 sec)
mysql> show columns from demo; --查看表结构
mysql> desc demo; --查看表结构
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| name | varchar(16) | NO | | NULL | |
| age | int(11) | YES | | NULL | |
| sex | enum('w','m') | NO | | m | |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql>drop table if exists mytab; -- 尝试删除mytab表格
数据操作:
--添加一条数据
mysql> insert into demo(name,age,sex) values('zhangsan',20,'w');
Query OK, 1 row affected (0.00 sec)
--不指定字段名来添加数据
mysql> insert into demo values('lisi',22,'m');
Query OK, 1 row affected (0.00 sec)
--指定部分字段名来添加数据
mysql> insert into demo(name,age) values('wangwu',23);
Query OK, 1 row affected (0.00 sec)
--批量添加数据
mysql> insert into demo(name,age,sex) values('aaa',21,'w'),("bbb",22,'m');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from demo; --查询数据
mysql> update demo set age=24 where name='aaa'; --修改
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> delete from demo where name='bbb'; --删除
Query OK, 1 row affected (0.00 sec)
1.15.3 MySQL数据结构类型及操作:
MySQL的数据类型分为三个类:数值类型、字串类型、日期类型 。 还有一个特殊的值:NULL。
1 数值类型:
*tinyint(1字节) 0~255 -128~127
smallint(2字节)
mediumint(3字节)
*int(4字节)
bigint(8字节)
*float(4字节) float(6,2)
*double(8字节)
decimal(自定义)字串形数值
2 字串类型
普通字串
*char 定长字串 char(8)
*varchar 可变字串 varchar(8)
二进制类型
tinyblob
blob
mediumblob
longblob
文本类型
tinytext
*text 常用于<textarea></textarea>
mediumtext
longtext
*enum枚举
set集合
3 时间和日期类型:
date 年月日
time 时分秒
*datetime 年月日时分秒
timestamp 时间戳
year 年
4 NULL值
NULL意味着“没有值”或“未知值”
可以测试某个值是否为NULL
不能对NULL值进行算术计算
对NULL值进行算术运算,其结果还是NULL
0或NULL都意味着假,其余值都意味着真
MySQL的运算符:
算术运算符:+ - * / %
比较运算符:= > < >= <= <> !=
数据库特有的比较:in,not in, is null,is not null,like, between and
逻辑运算符:and or not
表的字段约束:
unsigned 无符号(正数)
zerofill 前导零填充
auto_increment 自增
default 默认值
not null 非空
PRIMARY KEY 主键 (非null并不重复)
unique 唯一性 (可以为null但不重复)
index 常规索引
建表语句格式:
create table 表名(
字段名 类型 [字段约束],
字段名 类型 [字段约束],
字段名 类型 [字段约束],
...
);
mysql> create table stu(
-> id int unsigned not null auto_increment primary key,
-> name varchar(8) not null unique,
-> age tinyint unsigned,
-> sex enum('m','w') not null default 'm',
-> classid char(6)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> desc stu;
+---------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(8) | NO | UNI | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
| sex | enum('m','w') | NO | | m | |
| classid | char(6) | YES | | NULL | |
+---------+---------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> show create table stu\G --查看建表的语句
*************************** 1. row ***************************
Table: stu
Create Table: CREATE TABLE `stu` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(8) NOT NULL,
`age` tinyint(3) unsigned default NULL,
`sex` enum('m','w') NOT NULL default 'm',
`classid` char(6) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
修改表结构:
格式: alter table 表名 action(更改选项);
更改选项:
1. 添加字段:alter table 表名 add 字段名信息
例如:
-- 在user表的最后追加一个num字段 设置为int not null
mysql> alter table user add num int not null;
-- 在user表的email字段后添加一个age字段,设置int not null default 20;
mysql> alter table user add age int not null default 20 after email;
-- 在user表的最前面添加一个aa字段设置为int类型
mysql> alter table user add aa int first;
2. 删除字段:alter table 表名 drop 被删除的字段名
例如:-- 删除user表的aa字段
mysql> alter table user drop aa;
3. 修改字段:alter table 表名 change[modify] 被修改后的字段信息
其中:change可以修改字段名, modify 不修改
例如:
-- 修改user表中age字段信息(类型),(使用modify关键字的目的不修改字段名)
mysql> alter table user modify age tinyint unsigned not null default 20;
-- 修改user表的num字段改为mm字段并添加了默认值(使用change可以改字段名)
mysql> alter table user change num mm int not null default 10;
4. 添加和删除索引
-- 为user表中的name字段添加唯一性索引,索引名为uni_name;
mysql> alter table user add unique uni_name(name);
-- 为user表中的email字段添加普通索引,索引名为index_eamil
mysql> alter table user add index index_email(email);
-- 将user表中index_email的索引删除
mysql> alter table user drop index index_email;
5. 更改表名称:
ALTER TABLE 旧表名 RENAME AS 新表名
6. 更改AUTO_INCREMENT初始值:
ALTER TABLE 表名称 AUTO_INCREMENT=1
7. 更改表类型:
ALTER TABLE 表名称 ENGINE="InnoDB"
MySQL数据库中的表类型一般常用两种:MyISAM和InnoDB
区别:MyISAM类型的数据文件有三个frm(结构)、MYD(数据)、MYI(索引)
MyISAM类型中的表数据增 删 改速度快,不支持事务,没有InnoDB安全。
InnoDB类型的数据文件只有一个 .frm
InnoDB类型的表数据增 删 改速度没有MyISAM的快,但支持事务,相对安全。
1.15.4 数据的DML操作:添加数据,修改数据,删除数据
添加数据:
格式: insert into 表名[(字段列表)] values(值列表...);
--标准添加(指定所有字段,给定所有的值)
mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138');
Query OK, 1 row affected (0.13 sec)
mysql>
--指定部分字段添加值
mysql> insert into stu(name,classid) value('lisi','lamp138');
Query OK, 1 row affected (0.11 sec)
-- 不指定字段添加值
mysql> insert into stu value(null,'wangwu',21,'w','lamp138');
Query OK, 1 row affected (0.22 sec)
-- 批量添加值
mysql> insert into stu values
-> (null,'zhaoliu',25,'w','lamp94'),
-> (null,'uu01',26,'m','lamp94'),
-> (null,'uu02',28,'w','lamp92'),
-> (null,'qq02',24,'m','lamp92'),
-> (null,'uu03',32,'m','lamp138'),
-> (null,'qq03',23,'w','lamp94'),
-> (null,'aa',19,'m','lamp138');
Query OK, 7 rows affected (0.27 sec)
Records: 7 Duplicates: 0 Warnings: 0
修改操作:
格式:update 表名 set 字段1=值1,字段2=值2,字段n=值n... where 条件
-- 将id为11的age改为35,sex改为m值
mysql> update stu set age=35,sex='m' where id=11;
Query OK, 1 row affected (0.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 将id值为12和14的数据值sex改为m,classid改为lamp92
mysql> update stu set sex='m',classid='lamp92' where id=12 or id=14 --等价于下面
mysql> update stu set sex='m',classid='lamp92' where id in(12,14);
Query OK, 2 rows affected (0.09 sec)
Rows matched: 2 Changed: 2 Warnings: 0
删除操作:
格式:delete from 表名 [where 条件]
-- 删除stu表中id值为100的数据
mysql> delete from stu where id=100;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值为20到30的数据
mysql> delete from stu where id>=20 and id<=30;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值为20到30的数据(等级于上面写法)
mysql> delete from stu where id between 20 and 30;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值大于200的数据
mysql> delete from stu where id>200;
Query OK, 0 rows affected (0.00 sec)
1.15.5 数据的DQL操作:数据查询
格式:
select [字段列表]|* from 表名
[where 搜索条件]
[group by 分组字段 [having 子条件]]
[order by 排序 asc|desc]
[limit 分页参数]
各种查询:
mysql> select * from stu;
+----+----------+-----+-----+---------+
| id | name | age | sex | classid |
+----+----------+-----+-----+---------+
| 1 | zhangsan | 20 | m | lamp138 |
| 2 | lisi | 20 | m | lamp138 |
| 3 | wangwu | 21 | w | lamp138 |
| 4 | zhaoliu | 25 | w | lamp94 |
| 5 | uu01 | 26 | m | lamp94 |
| 6 | uu02 | 28 | w | lamp92 |
| 7 | qq02 | 24 | m | lamp92 |
| 8 | uu03 | 32 | m | lamp138 |
| 9 | qq03 | 23 | w | lamp94 |
| 10 | aa | 19 | m | lamp138 |
| 11 | sad | 35 | m | lamp94 |
| 12 | tt | 25 | m | lamp92 |
| 13 | wer | 25 | w | lamp94 |
| 14 | xx | 25 | m | lamp92 |
| 15 | kk | 0 | w | lamp94 |
+----+----------+-----+-----+---------+
15 rows in set (0.00 sec)
1. where条件查询
1. 查询班级为lamp138期的学生信息
mysql> select * from stu where classid='lamp138';
2. 查询lamp138期的男生信息(sex为m)
mysql> select * from stu where classid='lamp138' and sex='m';
3. 查询id号值在10以上的学生信息
mysql> select * from stu where id>10;
4. 查询年龄在20至25岁的学生信息
mysql> select * from stu where age>=20 and age<=25;
mysql> select * from stu where age between 20 and 25;
5. 查询年龄不在20至25岁的学生信息
mysql> select * from stu where age not between 20 and 25;
mysql> select * from stu where age<20 or age>25;
6. 查询id值为1,8,4,10,14的学生信息
select * from stu where id in(1,8,4,10,14);
mysql> select * from stu where id=1 or id=8 or id=4 or id=10 or id=14;
7. 查询lamp138和lamp94期的女生信息
mysql> select * from stu where classid in('lamp138','lamp94') and sex='w';
mysql> select * from stu where (classid='lamp138' or classid='lamp94') and sex='w
1.15.6 数据库授权、备份和恢复
授权:
格式:grant 允许操作 on 库名.表名 to 账号@来源 identified by '密码';
--实例:创建zhangsan账号,密码123,授权lamp61库下所有表的增/删/改/查数据,来源地不限
mysql> grant select,insert,update,delete on lamp61.* to zhangsan@'%' identified by '123';
mysql> grant all on *.* to zhangsan@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
-- 授权一个用户(zhangsan)密码123,可以对所有的库,所有的表做所有操作。
mysql> grant all on *.* to zhangsan@'%' identified by '123';
Query OK, 0 rows affected (0.17 sec)
--刷新生效,否则就要重启MySQL服务才可以。
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
--浏览当前MySQL用户信息
mysql> select user,host,password from mysql.user;
+----------+-----------------+-------------------------------------------+
| user | host | password |
+----------+-----------------+-------------------------------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| root | 127.0.0.1 | |
| | localhost | |
| zhangsan | % | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| admin | 192.168.112.132 | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
+----------+-----------------+-------------------------------------------+
5 rows in set (0.00 sec)
-- 移除一些权限
-- revoke:只删除了用户权限,但没有删除这个用户
mysql> revoke insert,delete on *.* from admin@192.168.112.132 identified by'123';
-- 查看指定用户的权限信息
mysql> show grants for xbb@localhost;
+------------------------------------------------------------------------------------------------------------+
| Grants for xbb@localhost |
+------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'xbb'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
+------------------------------------------------------------------------------------------------------------+
--drop user:删除了整个用户及其权限(包括数据字典中的数据)
mysql> drop user 'xbb'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| root | 127.0.0.1 |
| debian-sys-maint | localhost |
| root | localhost |
| root | wangxg |
+------------------+-----------+
4 rows in set (0.00 sec)
备份与恢复(导入和导出)
-- 将lamp138库导出
D:\>mysqldump -u root -p lamp138 >lamp138.sql
Enter password:
---- 将lamp138库中的stu表导出
D:\>mysqldump -u root -p lamp138 stu >lamp138_stu.sql
Enter password:
-- 将lamp138库导入
D:\>mysql -u root -p lamp138<lamp138.sql
Enter password:
-- 将lamp138库中stu表导入
D:\>mysql -u root -p lamp138<lamp138_stu.sql
Enter password:
1.15.7 MySQL的多表联查
- 表之间的关系有:1对1 1对多 多对多
1. 嵌套查询:一个查询的结果是另外sql查询的条件:
如:查询stu表中年龄最大的是谁?
mysql> select * from stu where age=(select max(age) from stu);
mysql> select * from stu where age in(select max(age) from stu); --(子查询结果是多条时使用in查询)
+----+------+------+-----+----------+
| id | name | age | sex | classid |
+----+------+------+-----+----------+
| 14 | abc | 33 | w | python01 |
+----+------+------+-----+----------+
1 row in set (0.01 sec)
2. where关联查询
已知:员工personnel表和部门department表,其中员工表中的did字段为部门表id主键关联。
查询所有员工信息,并显示所属部门名称
要求:显示字段:员工id 部门 姓名
mysql> select p.id,d.name,p.name from personnel p,department d where p.did = d.id;
+----+-----------+-----------+
| id | name | name |
+----+-----------+-----------+
| 2 | 人事部 | 李玉刚 |
| 10 | 人事部 | 阿杜 |
| 4 | 市场部 | 刘欢 |
。。。。
3. 连接join查询
左联:left join
右联:right join
内联:inner join
已知如下表所示,商品类别信息表(具有两层类别关系,通过pid表示,0表示一级类别)
mysql> select * from type;
+----+-----------+------+
| id | name | pid |
+----+-----------+------+
| 1 | 服装 | 0 |
| 2 | 数码 | 0 |
| 3 | 男装 | 1 |
| 4 | 手机 | 2 |
| 5 | 相机 | 2 |
| 6 | 电脑 | 2 |
| 7 | 女装 | 1 |
| 8 | 童装 | 1 |
| 9 | 食品 | 0 |
| 10 | 零食 | 9 |
| 11 | 特产 | 9 |
| 12 | 休闲装 | 1 |
+----+-----------+------+
12 rows in set (0.00 sec)
mysql> desc type;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| pid | int(10) unsigned | YES | | NULL | |
+-------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
-- 查询二级类别信息,并关联出他们的父类别名称
mysql> select t1.id,t1.name,t2.name from type t1,type t2 where t1.pid!=0 and t1.pid=t2.id;
+----+-----------+--------+
| id | name | name |
+----+-----------+--------+
| 3 | 男装 | 服装 |
| 4 | 手机 | 数码 |
| 5 | 相机 | 数码 |
| 6 | 电脑 | 数码 |
| 7 | 女装 | 服装 |
| 8 | 童装 | 服装 |
| 10 | 零食 | 食品 |
| 11 | 特产 | 食品 |
| 12 | 休闲装 | 服装 |
+----+-----------+--------+
9 rows in set (0.01 sec)
--统计每个一级类别下都有多少个子类别。
mysql> select t1.id,t1.name,count(t2.id) from type t1,type t2 where t1.pid=0 and t1.id=t2.pid group by t1.id;
+----+--------+--------------+
| id | name | count(t2.id) |
+----+--------+--------------+
| 1 | 服装 | 4 |
| 2 | 数码 | 3 |
| 9 | 食品 | 2 |
+----+--------+--------------+
3 rows in set (0.00 sec)
1.15.8 MySQL的其他操作
1. MySQL的表复制
复制表结构
mysql> create table 目标表名 like 原表名;
复制表数据
mysql> insert into 目标表名 select * from 原表名;
2. 数据表的索引
创建索引
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)
删除索引
DROP INDEX index_name ON talbe_name
3. mysql视图
创建视图:
mysql> create view v_t1 as select * from t1 where id>4 and id<11;
Query OK, 0 rows affected (0.00 sec)
view视图的帮助信息:
mysql> ? view
ALTER VIEW
CREATE VIEW
DROP VIEW
查看视图:
mysql> show tables;
删除视图v_t1:
mysql> drop view v_t1;
4. MySQL的内置函数
字符串处理函数
---------------------------------------------
*concat(s1,s2,…Sn) 连接s1,s2..Sn为一个字符串
insert(str,x,y,instr)将字符串str从第xx位置开始,y字符串的子字符串替换为字符串str
lower(str)将所有的字符串变为小写
upper(str)将所有的字符串变为大写
left(str,x)返回字符串中最左边的x个字符
rigth(str,y)返回字符串中最右边的x个字符
lpad(str,n,pad)用字符串pad对str最左边进行填充,直到长度为n个字符串长度
rpad(str,n,pad)用字符串pad对str最右边进行填充,直到长度为n个字符串长度
trim(str) 去掉左右两边的空格
ltrim(str) 去掉字符串str左侧的空格
rtrim(str) 去掉字符串str右侧的空格
repeat(str,x) 返回字符串str重复x次
replace(str,a,b)将字符串的的a替换成b
strcmp(s1,s2) 比较字符串s1和s2
substring(s,x,y)返回字符串指定的长度
*length(str) 返回值为字符串str 的长度
数值函数
-----------------------------------------------------
*abs(x) 返回x的绝对值
ceil(x) 返回大于x的最小整数值
floor(x) 返回小于x的最大整数值
mod(x,y) 返回x/y的取余结果
rand() 返回0~1之间的随机数
*round(x,y)返回参数x的四舍五入的有y位小数的值
truncate(x,y) 返回x截断为y位小数的结果
日期和时间函数
---------------------------------------------------
curdate() 返回当前日期,按照’YYYY-MM-DD’格式
curtime() 返回当前时间,当前时间以'HH:MM:SS'
*now() 返回当前日期和时间,
*unix_timestamp(date) 返回date时间的unix时间戳
from_unixtime(unix_timestamp[,format]) 返回unix时间的时间
week(date) 返回日期是一年中的第几周
year(date) 返回日期的年份
hour(time) 返回time的小时值
minute(time) 返回日time的分钟值
monthname(date) 返回date的月份
*date_fomat(date,fmt) 返回按字符串fmt格式化日期date值
date_add(date,INTERVAL,expr type) 返回一个日期或者时间值加上一个时间间隔的时间值
*datediff(expr,expr2) 返回起始时间和结束时间的间隔天数
//统计时间戳647583423距离当前时间相差天数(生日天数(不考虑年份))
mysql> select datediff(date_format(from_unixtime(647583423),"2017-%m-%d %h:%i:%s"),now());
其他常用函数
------------------------------------------------------
*database() 返回当前数据库名
version() 返回当前服务器版本
user() 返回当前登陆用户名
inet_aton 返回当前IP地址的数字表示 inet_aton("192.168.80.250");
inet_ntoa(num) 返回当前数字表示的ip inet_ntoa(3232256250);
*password(str) 返回当前str的加密版本
*md5(str) 返回字符串str的md5值
5. MySQL的事务处理
关闭自动提交功能(开启手动事务)
mysql> set autocommit=0;
从表t1中删除了一条记录
mysql> delete from t1 where id=11;
此时做一个p1还原点:
mysql> savepoint p1;
再次从表t1中删除一条记录:
mysql> delete from t1 where id=10;
再次做一个p2还原点:
mysql> savepoint p2;
此时恢复到p1还原点,当然后面的p2这些还原点自动会失效:
mysql> rollback to p1;
退回到最原始的还原点:
mysql> rollback;
回滚
开启自动事务提交(关闭手动事务)
mysql> set autocommit=1;
6. MySQL的触发器
格式:1、触发器的定义:
CREATE TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt
说明:
# trigger_name:触发器名称
# trigger_time:触发时间,可取值:BEFORE或AFTER
# trigger_event:触发事件,可取值:INSERT、UPDATE或DELETE。
# tb1_name:指定在哪个表上
# trigger_stmt:触发处理SQL语句。
示例:
mysql> delimiter $$
mysql> create trigger del_stu before delete on stu for each row
-> begin
-> insert into stu_bak values(old.id,old.name,old.sex,old.age,old.addtime);
-> end;
-> $$
Query OK, 0 rows affected (0.05 sec)
mysql> delimiter ;
7. mysql日志
开启日志: 在mysql配置文件中开启:log-bin=mysql-bin
查看bin-log日志:
mysql>show binary logs;
查看最后一个bin-log日志:
mysql>show master status;
此时就会多一个最新的bin-log日志
mysql>flush logs;
查看最后一个bin日志.
mysql>show master status;
mysql>reset master;
清空所有的bin-log日志
执行查看bin-log日志
备份数据:
mysqldump -uroot -pwei test -l -F '/tmp/test.sql'
其中:-F即flush logs,可以重新生成新的日志文件,当然包括log-bin日志
// Linux关闭MySQL的命令
$mysql_dir/bin/mysqladmin -uroot -p shutdown
// linux启动MySQL的命令
$mysql_dir/bin/mysqld_safe &
8、有关慢查询操作:
开户和设置慢查询时间:
vi /etc/my.cnf
log_slow_queries=slow.log
long_query_time=5
查看设置后是否生效
mysql> show variables like "%quer%";
慢查询次数:
mysql> show global status like "%quer%";
9 数据库的恢复
1. 首先恢复最后一次的备份完整数据
[root@localhost mnt]# mysql -u root -p mydemo<mydemo_2017-7-26.sql
Enter password:
2. 查看bin-log日志
[root@localhost data]# mysqlbinlog --no-defaults mysql-bin.000009;
查找到恢复的节点
3. 执行bin-log日志文件,恢复最后一块的增量数据。
[root@localhost data]# mysqlbinlog --no-defaults --stop-position="802" mysql-bin.000009|mysql -u ro
1.16 Python的数据库支持
1.16.1. 什么是 PyMySQL?
- PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。
- PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。
1.16.2. PyMySQL安装
- PyMySQL下载地址:https://github.com/PyMySQL/PyMySQL。
2.1 使用pip命令进行安装:
$ pip install PyMySQL
2.2 使用 git 命令下载安装包安装(你也可以手动下载):
$ git clone https://github.com/PyMySQL/PyMySQL
$ cd PyMySQL/
$ python3 setup.py install
1.16.3. 数据库连接
3.1 通过如下代码测试数据库连接
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL 查询
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()
print ("Database version : %s " % data)
# 关闭数据库连接
db.close()
3.2 执行数据查询
#!/usr/bin/python3
import pymysql
#打开数据库连接
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")
#使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()
#定义查询sql语句
#sql = "select * from stu"
sql = "select * from stu where classid='%s'"%("python03")
try:
# 使用execute()方法执行SQL查询
cursor.execute(sql)
print("本次查询条数:",cursor.rowcount)
'''
# 使用fetchone()方法获取单条数据.
while True:
data = cursor.fetchone();
if data == None:
break;
print (data)
'''
#使用fetchall()获取所有结果
alist = cursor.fetchall()
for vo in alist:
print(vo)
except Exception as err:
print("SQL执行错误,原因:",err)
# 关闭数据库连接
db.close()
3.3 执行数据添加
#!/usr/bin/python3
import pymysql
#打开数据库连接
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")
#使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()
#定义添加sql语句
data = ("uu100",28,'w','python05')
sql = "insert into stu(name,age,sex,classid) values('%s','%d','%s','%s')"%(data)
try:
# 使用execute()方法执行SQL
m = cursor.execute(sql)
# 事务提交
db.commit()
print("成功操作条数:",m)
#print("成功操作条数:",cursor.rowcount)
except Exception as err:
#事务回滚
db.rollback()
print("SQL执行错误,原因:",err)
# 关闭数据库连接
db.close()
3.4 执行删除操作
#!/usr/bin/python3
import pymysql
#打开数据库连接
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")
#使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()
#定义删除sql语句
sql = "delete from stu where id=%d"%(100)
try:
# 使用execute()方法执行SQL
cursor.execute(sql)
# 事务提交
db.commit()
print("成功删除条数:",cursor.rowcount)
except Exception as err:
#事务回滚
db.rollback()
print("SQL执行错误,原因:",err)
# 关闭数据库连接
db.close()
数据库查询操作:
- Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。
- fetchone(): 该方法获取下一个查询结果集。结果集是一个对象,最后返回None结束
- fetchall(): 接收全部的返回结果行.
- rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。
附录:pip命令
------------------------------------------------------------
列出已安装的包:
$ pip list
$ pip freeze # 查看自己安装的
安装软件(安装特定版本的package,通过使用==, >=, <=, >, <来指定一个版本号)**
$ pip install SomePackage
$ pip install 'Markdown<2.0'
$ pip install 'Markdown>2.0,<2.0.3'
卸载软件pip uninstall SomePackage
$ pip uninstall SomePackage
下载所需的软件包:
$ pip download SomePackage -d directory
例如下载PyMySQL软件包
$ pip download PyMySQL -d D:/pypackage
安装下载好的软件包文件
$ pip install 目录/软件包文件名
如安装PyMySQL软件包
$ pip3.6 install D:/pypackage/PyMySQL-0.7.11-py2.py3-none-any.whl
1.17 图形用户界面实战
- 本节介绍如何创建Python程序的图形用户界面(GUI),也就是那些带有按钮和文本框的窗口。
- 目前支持Python的所谓"GUI工具包"有很多,但没有一个被认为是标准的,也好,选择空间大
- GUI工具包:
工具包名 | 介绍 | URL地址 |
---|---|---|
Tkinter | 使用Tk平台。很容易得到。半标准 | http://wiki.python.org/moin/TkInter |
wxpython | 基于wxWindows。跨平台越来越流行 | http://wxpython.org |
PythonWin | 只能在Windows上使用。 | http://starship.python.net/crew/mhammond |
Java Swing | 只能用于Python。使用本机的Java GUI | http://java.sun.com/docs/books/tutorial/uiswing |
PyGTK | 使用GTK平台,在Linux上很流行 | http://pygtk.org |
PyQt | 使用Qt平台,跨平台 | http://wiki.python.org/moin/PyQt |
1.17.1 安装:wxpython
pip install -U wxpython
--Installing collected packages: six, wxpython
--Successfully installed six-1.11.0 wxpython-4.0.1
- 开发步骤:
1. 导入wx模块
2. 定义一个应用程序对象
3. 创建wx.Frame主窗口对象,设置窗口标题和大小
4. 创建组件、布局、添加事件处理等操作
5. 通过Frame的show()方法显示窗体
6. 进入应用程序事件主循环
1.17.2 创建并且显示一个框架
# 导入wxPython模块
import wx
# 创建应用程序对象
app = wx.App()
win = wx.Frame(None) #创建一个单独的窗口
btn=wx.Button(win) #创建一个按钮组件
win.Show() #设置可见
#进入应用程序事件主循环
app.MainLoop()
1.17.3 设置标题,添加按钮
import wx
app = wx.App()
win = wx.Frame(None,title="我的记事本") #创建一个单独的窗口
loadButton = wx.Button(win,label="Open")
saveButton = wx.Button(win,label="Save")
win.Show()
app.MainLoop() #进入应用程序事件主循环
1.17.4 设置标题,添加按钮,并简单布局
import wx
app = wx.App()
win = wx.Frame(None,title="我的记事本",size=(410,335)) #创建一个单独的窗口
loadButton = wx.Button(win,label="Open",pos=(225,5),size=(80,25))
saveButton = wx.Button(win,label="Save",pos=(315,5),size=(80,25))
filename = wx.TextCtrl(win,pos=(5,5),size=(210,25))
contents = wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)
win.Show()
app.MainLoop() #进入应用程序事件主循环
1.17.5 组件布局
import wx
app = wx.App()
win = wx.Frame(None,title="我的记事本",size=(410,335)) #创建一个单独的窗口
bkg = wx.Panel(win)
#创建组件
loadButton = wx.Button(bkg,label="Open")
saveButton = wx.Button(bkg,label="Save")
filename = wx.TextCtrl(bkg)
contents = wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)
#布局容器
hbox=wx.BoxSizer() #默认水平布局
hbox.Add(filename,proportion=1,flag=wx.EXPAND)
hbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)
hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)
#布局容器
vbox=wx.BoxSizer(wx.VERTICAL) #垂直布局
vbox.Add(hbox,proportion=0,flag=wx.EXPAND|wx.ALL,border=5)
vbox.Add(contents,proportion=1,flag=wx.EXPAND|wx.LEFT|wx.BOTTOM|wx.RIGHT,border=50)
bkg.SetSizer(vbox)
win.Show()
app.MainLoop() #进入应用程序事件主循环
1.17.6 为按钮添加事件并完成其事件处理操作
import wx
#按钮事件处理函数
def load(event):
'''加载文件内容'''
file=open(filename.GetValue(),"r")
contents.SetValue(file.read())
file.close()
def save(event):
'''保持文件内容'''
file=open(filename.GetValue(),"w")
file.write(contents.GetValue())
file.close()
#
app = wx.App()
win = wx.Frame(None,title="我的记事本",size=(410,335)) #创建一个单独的窗口
win.Show()
loadButton = wx.Button(win,label="Open",pos=(225,5),size=(80,25))
saveButton = wx.Button(win,label="Save",pos=(315,5),size=(80,25))
loadButton.Bind(wx.EVT_BUTTON,load)
saveButton.Bind(wx.EVT_BUTTON,save)
filename = wx.TextCtrl(win,pos=(5,5),size=(210,25))
contents = wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)
app.MainLoop() #进入应用程序事件主循环
1.18 阶段案例实战 :《飞机游戏》
- 本次开发需要安装一个Python的游戏模块:pygame。 方式:
pip install pygame
开发步骤如下:
1.18.1 创建游戏主页面窗口,并添加滚动背景。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccaHcpaT-1603700619117)(https://edu.csdn.net/notebook/python/images/week02/11.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time
# 创建游戏主页面窗口,并添加滚动背景。
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.18.2 添加键盘事件处理函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-94d6RkfS-1603700619117)(https://edu.csdn.net/notebook/python/images/week02/22.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time
# 添加键盘事件处理函数。
def key_control(hero_temp):
''' 键盘控制函数 '''
#获取事件,比如按键等
for event in pygame.event.get():
#判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
#获取按下的键(返回的是元组值)
pressed_keys = pygame.key.get_pressed()
#检测是否按下a或者left键
if pressed_keys[K_LEFT] or pressed_keys[K_a]:
print('left')
#检测是否按下d或者right键
elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
print('right')
#检查是否是空格键
if pressed_keys[K_SPACE]:
print('space')
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
# 调用键盘控制函数
key_control(None)
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.18.3 放置玩家英雄飞机,并绑定键盘事件,实现飞机移动
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-INKpnfss-1603700619118)(https://edu.csdn.net/notebook/python/images/week02/33.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time
# 放置玩家英雄飞机,并绑定键盘事件,实现飞机移动
class HeroPlane:
''' 玩家飞机类(英雄) '''
def __init__(self, screen_temp):
self.x = 200
self.y = 400
self.screen = screen_temp
self.image = pygame.image.load("./images/me.png")
def display(self):
''' 绘制玩家到窗口中 '''
self.screen.blit(self.image, (self.x, self.y))
def move_left(self):
''' 左移动,并判断防止越界 '''
self.x -= 5
if self.x<0:
self.x=0
def move_right(self):
''' 右移动,并判断防止越界 '''
self.x += 5
if self.x > 406:
self.x = 406
def key_control(hero_temp):
''' 键盘控制函数 '''
#获取事件,比如按键等
for event in pygame.event.get():
#判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
#获取按下的键(返回的是元组值)
pressed_keys = pygame.key.get_pressed()
#检测是否按下a或者left键
if pressed_keys[K_LEFT] or pressed_keys[K_a]:
print('left')
hero_temp.move_left()
#检测是否按下d或者right键
elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
print('right')
hero_temp.move_right()
#检查是否是空格键
if pressed_keys[K_SPACE]:
print('space')
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
#3. 创建一个玩家飞机对象
hero = HeroPlane(screen)
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
#显示英雄玩家
hero.display()
# 键盘控制(负责移动玩家)
key_control(hero)
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.18.4 添加玩家子弹,并实现发射
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pOTHMYle-1603700619119)(https://edu.csdn.net/notebook/python/images/week02/44.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time
# 添加玩家子弹,并实现发射。
class HeroPlane:
''' 玩家飞机类(英雄) '''
def __init__(self, screen_temp):
self.x = 200
self.y = 400
self.screen = screen_temp
self.image = pygame.image.load("./images/me.png")
self.bullet_list = [] #存储发射出去的子弹对象引用
def display(self):
''' 绘制玩家到窗口中 '''
#遍历移动子弹
for bullet in self.bullet_list:
bullet.display()
#移动子弹,并判断是否越界。
if bullet.move():
self.bullet_list.remove(bullet)
self.screen.blit(self.image, (self.x, self.y))
def move_left(self):
''' 左移动,并判断防止越界 '''
self.x -= 5
if self.x<0:
self.x=0
def move_right(self):
''' 右移动,并判断防止越界 '''
self.x += 5
if self.x > 406:
self.x = 406
def fire(self):
self.bullet_list.append(Bullet(self.screen, self.x, self.y))
print(len(self.bullet_list))
class Bullet:
''' 玩家子弹类 '''
def __init__(self, screen_temp, x, y):
self.x = x+51
self.y = y
self.screen = screen_temp
self.image = pygame.image.load("./images/pd.png")
def display(self):
self.screen.blit(self.image, (self.x, self.y))
def move(self):
self.y-=10
if self.y<-20:
return True
def key_control(hero_temp):
''' 键盘控制函数 '''
#获取事件,比如按键等
for event in pygame.event.get():
#判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
#获取按下的键(返回的是元组值)
pressed_keys = pygame.key.get_pressed()
#检测是否按下a或者left键
if pressed_keys[K_LEFT] or pressed_keys[K_a]:
print('left')
hero_temp.move_left()
#检测是否按下d或者right键
elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
print('right')
hero_temp.move_right()
#检查是否是空格键
if pressed_keys[K_SPACE]:
print('space')
hero_temp.fire()
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
#3. 创建一个玩家飞机对象
hero = HeroPlane(screen)
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
#显示英雄玩家
hero.display()
# 键盘控制(负责移动玩家)
key_control(hero)
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.18.5 随机显示敌机
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPBrAEyI-1603700619120)(https://edu.csdn.net/notebook/python/images/week02/55.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time,random
# 显示敌机。
class HeroPlane:
''' 玩家飞机类(英雄) '''
def __init__(self, screen_temp):
self.x = 200
self.y = 400
self.screen = screen_temp
self.image = pygame.image.load("./images/me.png")
self.bullet_list = [] #存储发射出去的子弹对象引用
def display(self):
''' 绘制玩家到窗口中 '''
#遍历移动子弹
for bullet in self.bullet_list:
bullet.display()
#移动子弹,并判断是否越界。
if bullet.move():
self.bullet_list.remove(bullet)
self.screen.blit(self.image, (self.x, self.y))
def move_left(self):
''' 左移动,并判断防止越界 '''
self.x -= 5
if self.x<0:
self.x=0
def move_right(self):
''' 右移动,并判断防止越界 '''
self.x += 5
if self.x > 406:
self.x = 406
def fire(self):
self.bullet_list.append(Bullet(self.screen, self.x, self.y))
print(len(self.bullet_list))
class Bullet:
''' 玩家子弹类 '''
def __init__(self, screen_temp, x, y):
self.x = x+51
self.y = y
self.screen = screen_temp
self.image = pygame.image.load("./images/pd.png")
def display(self):
self.screen.blit(self.image, (self.x, self.y))
def move(self):
self.y-=10
if self.y<-20:
return True
class EnemyPlane:
"""敌机的类"""
def __init__(self, screen_temp):
self.x = random.choice(range(408))
self.y = -75
self.screen = screen_temp
self.image = pygame.image.load("./images/e2.png")
def display(self):
self.screen.blit(self.image, (self.x, self.y))
def move(self):
self.y += 4
def key_control(hero_temp):
''' 键盘控制函数 '''
#获取事件,比如按键等
for event in pygame.event.get():
#判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
#获取按下的键(返回的是元组值)
pressed_keys = pygame.key.get_pressed()
#检测是否按下a或者left键
if pressed_keys[K_LEFT] or pressed_keys[K_a]:
print('left')
hero_temp.move_left()
#检测是否按下d或者right键
elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
print('right')
hero_temp.move_right()
#检查是否是空格键
if pressed_keys[K_SPACE]:
print('space')
hero_temp.fire()
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
#3. 创建一个玩家飞机对象
hero = HeroPlane(screen)
#4. 定义用于存放敌机列表
enemylist = []
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
#显示英雄玩家
hero.display()
# 键盘控制(负责移动玩家)
key_control(hero)
#随机输出敌机
if random.choice(range(50))==10:
enemylist.append(EnemyPlane(screen))
#遍历所有敌机,显示敌机,移动敌机
for em in enemylist:
em.display()
em.move()
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.18.6 实现敌机与子弹的碰撞检测
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gK0TBpJN-1603700619121)(https://edu.csdn.net/notebook/python/images/week02/66.png)]
# -*- coding:utf-8 -*-
import pygame
from pygame.locals import * #pygame使用的各种常量
import time,random
# 实现敌机与子弹的碰撞检测。
class HeroPlane:
''' 玩家飞机类(英雄) '''
def __init__(self, screen_temp):
self.x = 200
self.y = 400
self.screen = screen_temp
self.image = pygame.image.load("./images/me.png")
self.bullet_list = [] #存储发射出去的子弹对象引用
def display(self):
''' 绘制玩家到窗口中 '''
#遍历移动子弹
for bullet in self.bullet_list:
bullet.display()
#移动子弹,并判断是否越界。
if bullet.move():
self.bullet_list.remove(bullet)
self.screen.blit(self.image, (self.x, self.y))
def move_left(self):
''' 左移动,并判断防止越界 '''
self.x -= 5
if self.x<0:
self.x=0
def move_right(self):
''' 右移动,并判断防止越界 '''
self.x += 5
if self.x > 406:
self.x = 406
def fire(self):
self.bullet_list.append(Bullet(self.screen, self.x, self.y))
print(len(self.bullet_list))
class Bullet:
''' 玩家子弹类 '''
def __init__(self, screen_temp, x, y):
self.x = x+51
self.y = y
self.screen = screen_temp
self.image = pygame.image.load("./images/pd.png")
def display(self):
self.screen.blit(self.image, (self.x, self.y))
def move(self):
self.y-=10
if self.y<-20:
return True
class EnemyPlane:
"""敌机的类"""
def __init__(self, screen_temp):
self.x = random.choice(range(408))
self.y = -75
self.screen = screen_temp
self.image = pygame.image.load("./images/e"+str(random.choice(range(3)))+".png")
def display(self):
self.screen.blit(self.image, (self.x, self.y))
def move(self,hero):
self.y += 4
#遍历玩家的子弹,并做碰撞检测
for bo in hero.bullet_list:
if bo.x>self.x+12 and bo.x<self.x+92 and bo.y>self.y+20 and bo.y<self.y+60:
hero.bullet_list.remove(bo)
return True
#判断敌机是否越界
if self.y>512:
return True;
def key_control(hero_temp):
''' 键盘控制函数 '''
#获取事件,比如按键等
for event in pygame.event.get():
#判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
#获取按下的键(返回的是元组值)
pressed_keys = pygame.key.get_pressed()
#检测是否按下a或者left键
if pressed_keys[K_LEFT] or pressed_keys[K_a]:
print('left')
hero_temp.move_left()
#检测是否按下d或者right键
elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
print('right')
hero_temp.move_right()
#检查是否是空格键
if pressed_keys[K_SPACE]:
print('space')
hero_temp.fire()
def main():
'''游戏的主程序执行函数'''
#1. 创建窗口:set_mode(分辨率=(0,0),标志=0,深度=0)
screen = pygame.display.set_mode((512,568),0,0)
#2. 创建一个游戏背景图片(512*1536)
background = pygame.image.load("./images/bg2.jpg")
m=-968 #初始化游戏背景图片标轴y的值
#3. 创建一个玩家飞机对象
hero = HeroPlane(screen)
#4.定义用于存放敌机列表
enemylist = []
while True:
#绘制位图
screen.blit(background,(0,m))
m+=2
if m>=-200:
m = -968
#显示英雄玩家
hero.display()
# 键盘控制(负责移动玩家)
key_control(hero)
#随机输出敌机
if random.choice(range(50))==10:
enemylist.append(EnemyPlane(screen))
#遍历所有敌机,显示敌机,移动敌机,并与玩家子弹碰撞检测
for em in enemylist:
em.display()
if em.move(hero):
enemylist.remove(em)
#更新屏幕显示
pygame.display.update()
# 定时睡眠(时钟)
time.sleep(0.04)
# 判断当前是否是主程序,若是就执行主程序。
if __name__ == "__main__":
main()
1.19 Python扩展内容
① python中yield关键字的使用:
yield
是一个类似return
的关键字,只是这个函数返回的是个生成器- 当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象
- 当你使用for进行迭代的时候,函数中的代码才会执行
生成器
特点:可迭代;只能读取一次;实时生成数据,不全存在内存中。
def fun():
yield "aaa"
yield "bbb"
yield "ccc"
#返回可迭代对象(生成器)
a = fun()
print(a) # <generator object fun at 0x10f26e990>
#可以将迭代对象转成列表
# b = list(a)
# print(b) #['aaa', 'bbb', 'ccc']
#遍历(迭代)输出,注意:只能读取一次
for i in a:
print(i)
'''
aaa
bbb
ccc
'''
- 案例:
import json
#案例一、这是一段过程化代码编写:
str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
data = json.loads(str) #解码JSON数据
# 过滤出年龄大于20岁以上的信息,并输出
for item in data:
if item['age']>20:
#输出数据
print('-' * 20)
print(item['name'],":",item['age'])
'''
#输出结果:
--------------------
zhangsan : 22
--------------------
wangwu : 24
'''
#案例二:代码拆分(将数据的处理封装成函数):
def fun1():
str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
data = json.loads(str) #解码JSON数据
#过滤出年龄大于20岁以上的信息,并输出
dlist = []
for item in data:
if item['age']>20:
#将过滤出来的数据放置到dlist中
print('-' * 20)
dlist.append(item)
return dlist
# 使用(输出数据)
for i in fun1():
print(i['name'], ":", i['age'])
'''
#输出结果:
--------------------
--------------------
wangwu : 24
wangwu : 24
'''
#案例三:代码拆分(使用yield返回生成器):
def fun1():
str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
data = json.loads(str) #解码JSON数据
#过滤出年龄大于20岁以上的信息,并输出
for item in data:
if item['age']>20:
#将过滤出来的数据放置到dlist中
print('-' * 20)
yield item
# 使用(输出数据)
for i in fun1():
print(i['name'], ":", i['age'])
'''
#输出结果:
--------------------
zhangsan : 22
--------------------
wangwu : 24
'''
② 装饰器的使用:
-
python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,
-
使用python装饰器的好处就是在
不用更改原函数的代码前提下给函数增加新的功能
。 -
无参数的装饰器实例
# 无参数的装饰器实例
def deco(dd):
def _deco():
print("start....")
dd()
print("end.....")
return _deco
@deco
def demo():
print("demo()............")
if __name__ == "__main__":
d = demo
d()
#demo()
- 输出结果
start....
demo()............
end.....
# 带参数的装饰器实例
def deco(func):
def _deco(a, b):
print("before myfunc() called.")
ret = func(a, b)
print(" after myfunc() called. result: %s" % ret)
return ret
return _deco
@deco
def myfunc(a, b):
print(" myfunc(%s,%s) called." % (a, b))
return a + b
if __name__ == "__main__":
myfunc(1, 2)
myfunc(3, 4)
- 输出结果
before myfunc() called.
myfunc(1,2) called.
after myfunc() called. result: 3
before myfunc() called.
myfunc(3,4) called.
after myfunc() called. result: 7