一、Python复习教程(重点)- 基础

目录导航:

文章目录

  • 目录导航:
  • 一、Python基础
    • 1.1 Python安装和使用
      • 1.1.1 Python环境搭建
      • 1.1.2 运行Python
        • (1) 交互式解释器
        • (2) 命令行脚本
        • (3) 集成开发环境(IDE:Integrated Development Environment): PyCharm
    • 1.2 Python基础语法
      • 1.2.1 输入和输出
      • 1.2.2 注释
      • 1.2.3 标识符
      • 1.2.4 变量
      • 1.2.5 行与缩进
    • 1.3 Python运算符
        • (1) Python算术运算符
        • (2) Python比较运算符
        • (3) Python赋值运算符
        • (4) Python位运算符
        • (5) Python逻辑运算符
        • (6) Python成员运算符
        • (7) Python身份运算符
        • (8) Python运算符优先级
    • 1.4 Python数据类型
      • 1.4.1 标准数据类型
        • (1) Number(数字)
        • (2) String(字符串)
        • (3) List(列表)
        • (4) Tuple(元组)
        • (5) Set(集合)
        • (6) Dictionary(字典)
      • 1.4.2 Python数据类型转换
    • 1.5 Python分支结构
      • 1.5.1 流程控制
      • 1.5.2 分支/选择结构
        • (1) 单项分支
        • (2) 双项分支
        • (2) 多项分支
        • (4) 巢状分支
    • 1.6 Python循环结构
      • 1.6.1 while型循环
      • 1.6.2 for ... in 循环
      • 1.6.3 range()函数
      • 1.3.7 练习:逆向输出乘法口诀
      • 1.6.4 break和continue语句及循环中的else子句
    • 1.7 Python函数
      • 1.7.1 认识Python函数
      • 1.7.2 函数的定义格式
        • (1) 基本函数格式
        • (2) 带有参数的函数格式
        • (3) 带有默认值的参数
        • (4) 关键字参数
        • (5). 收集参数
        • (6) 多种参数混合
        • **关于返回值的问题
      • 1.7.3 函数文档
      • 1.7.4 局部变量与全局变量
      • 1.7.5 函数其他使用
        • (1) 匿名函数
    • 1.8 Python数据类型的操作
      • 1.8.1 Number数字
      • 1.8.2 String字符串
      • (1) Python转义字符
      • (2) Python字符串运算符
        • (3) Python字符串格式化
        • (4) Python 的字符串内建函数
      • 1.8.3 List列表
        • (1) 列表的遍历操作:
        • (2) Python列表脚本操作符
        • (3) Python列表截取与拼接
        • (4) Python列表函数&方法
      • 1.8.4 Tuple元组
        • (1) 元组运算符
        • (2)元组索引,截取
        • (3) 元组内置函数
      • 1.8.5 Sets集合
        • (1) 集合的遍历
        • (2) 集合的序列函数
        • (3) 集合中的方法
      • 1.8.6 Dictionary字典
        • (1) 创建字典
        • (2) 字典的基本操作
    • 1.9 Python文件操作
        • (1) 文件的基本操作
        • (2) OS模块
    • 1.10 综合案例实战
        • 使用python学习内容实现一个在线学员信息管理操作
          • 初识界面:
          • 添加学员信息
          • 浏览学员信息
          • 删除学员信息
          • 退出操作
        • 参考程序代码如下:
  • 二、Python基础进阶
    • 1.11 Python面向对象编程
      • 面向对象技术简介
      • 1.11.2 类和对象
      • 1.11.3 构造函数
      • 1.11.4 类的属性和方法
          • **类的方法:**
      • 1.11.5 继承与重载
          • 多继承:
          • 方法重写:
      • 1.11.6 其他
    • 1.12 Python中的异常处理
      • 1.12.1 异常介绍
          • 附加:Python—内建异常体系结构
      • 1.12.2 异常处理
          • 异常处理实例
      • 1.12.3 抛出异常(自行抛出异常)
    • 1.13 魔术方法、属性和迭代器
      • 1.13.1 魔术方法:
      • 1.13.2 属性和方法
          • property() 函数的作用是在新式类中返回属性值
          • 静态方法和类成员方法(区别是有无带参数)
      • 1.13.3 迭代器:
    • 1.14 Python模块实战
      • 1.14.1 什么是Python模块
      • 1.14.2 Python模块的导入
        • (1) import 语句
        • (2) from…import 语句
      • 1.14.3 第三方模块的安装
      • 1.14.4 自定义Python模块
    • 1.15 MySQL数据库基础
      • 1.15.1 MySQL简介
          • SQL:
          • mysql数据库的安装:
          • 连接数据库:
      • 1.15.2. SQL的基本操作
          • 数据库操作:
          • 数据表操作:
          • 数据操作:
      • 1.15.3 MySQL数据结构类型及操作:
          • MySQL的数据类型分为三个类:数值类型、字串类型、日期类型 。 还有一个特殊的值:NULL。
          • MySQL的运算符:
          • 表的字段约束:
          • 建表语句格式:
          • 修改表结构:
      • 1.15.4 数据的DML操作:添加数据,修改数据,删除数据
          • 添加数据:
          • 修改操作:
          • 删除操作:
      • 1.15.5 数据的DQL操作:数据查询
          • 格式:
          • 各种查询:
      • 1.15.6 数据库授权、备份和恢复
          • 授权:
          • 备份与恢复(导入和导出)
      • 1.15.7 MySQL的多表联查
      • 1.15.8 MySQL的其他操作
    • 1.16 Python的数据库支持
      • 1.16.1. 什么是 PyMySQL?
      • 1.16.2. PyMySQL安装
          • 2.1 使用pip命令进行安装:
          • 2.2 使用 git 命令下载安装包安装(你也可以手动下载):
      • 1.16.3. 数据库连接
          • 3.1 通过如下代码测试数据库连接
          • 3.2 执行数据查询
          • 3.3 执行数据添加
          • 3.4 执行删除操作
      • 数据库查询操作:
      • 附录:pip命令
    • 1.17 图形用户界面实战
      • 1.17.1 安装:wxpython
      • 1.17.2 创建并且显示一个框架
      • 1.17.3 设置标题,添加按钮
      • 1.17.4 设置标题,添加按钮,并简单布局
      • 1.17.5 组件布局
      • 1.17.6 为按钮添加事件并完成其事件处理操作
    • 1.18 阶段案例实战 :《飞机游戏》
      • 开发步骤如下:
      • 1.18.1 创建游戏主页面窗口,并添加滚动背景。
      • 1.18.2 添加键盘事件处理函数
      • 1.18.3 放置玩家英雄飞机,并绑定键盘事件,实现飞机移动
      • 1.18.4 添加玩家子弹,并实现发射
      • 1.18.5 随机显示敌机
      • 1.18.6 实现敌机与子弹的碰撞检测
    • 1.19 Python扩展内容
      • ① python中yield关键字的使用:
      • ② 装饰器的使用:

一、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. 算术运算符
    2. 比较(关系)运算符
    3. 赋值运算符
    4. 逻辑运算符
    5. 位运算符
    6. 成员运算符
    7. 身份运算符
    8. 运算符优先级

(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(字典)

(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中的字符串不能改变。

(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 "", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
  • 虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。
  • 构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:
tup1 = ()    # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
string、listtuple都属于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.整型转换之后变为 (整型+0j2.浮点型转换之后变为(浮点型 + 0j)
3.布尔值转化之后 True->1+0jFalse(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区间、

(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 
    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()
      • 函数执行完毕之后,会产生一个结果,可以被变量接受或者使用的函数
格式:

    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
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

(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))  # 

# 正确定义方式加上逗号,类型为元组
tup5 = (50,)
print(type(tup5))  # 

# 以下修改元组元素操作是非法的。
# 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)
  • 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):
    
    .
    .
    .
    
  • 需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,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 "", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "", 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异常体系结构如下图:

一、Python复习教程(重点)- 基础_第1张图片

常见的异常如下表所示:

异常名称 描述
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 "", 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 "", 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] #定义一个列表:
y = iter(x)   #创建一个可迭代对象:
#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      常用于
    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 [email protected] 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 lamp138mysql -u root -p lamp138

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

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) # 

#可以将迭代对象转成列表
# 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

你可能感兴趣的:(Python教程资料,笔记,python,数据库,mysql,面向对象编程,网络通信)