当前位置:首页python > 正文

python编程教程(小牛教编程)

作者:野牛程序员:2023-03-08 18:26:40python阅读 2443
第1章 Python 语法基础
1.1 标识符和关键字
1.1.1 标识符
1.1.2 关键字
1.2 变量和常量
1.2.1 变量
1.2.2 常量
1.3 注释
1.4 语句
1.5 模块
1.6 包
1.6.1 创建包
1.6.2 导入包
第2章 Python 编码规范
2.1 命名规范
2.2注释规范
2.2.1 文件注释
2.2.2 文档注释
2.2.3 代码注释
2.2.4 使用 TODO 注释
2.3 导入规范
2.4 代码排版
2.4.1 空行
2.4.2 空格 
2.4.3 缩进
2.4.4 断行
第3章 数据类型…
3.1 数字类型 ……
3.1.1 整数类型
3.1.2 浮点类型
3.1.3 复数类型
3.1.4 布尔类型
3.2 数字类型相互转换
3.2.1 隐式类型转换
3.2.2 显式类型转换
3.3 字符串类型
3.3.1 字符串表示方式
3.3.2 字符串格式化
3.3.3 字符串查找
3.3.4 字符串与数字相互转换
第4章 运算符
4.1 算术运算符
4.1.1 一元运算符
4.1.2 二元运算符
4.2 关系运算符
4.3 逻辑运算符
4.4 位运算符
4.5 赋值运算符
4.6 其他运算符
4.6.1 同一性测试运算符
4.6.2 成员测试运算符
4.7 运算符优先级
第5章控制语句
5.1 分支语句
5.1.1 if结构
5.1.2 if-else 结构
5.1.3 elif结构
5.1.4 三元运算符替代品--条件表达式
5.2 循环语句
5.2.1 while 语句
5.2.2 for 语句
5.3 跳转语句
5.3.1 break 语句
5.3.2 continue 语句
5.3.3 while 和 for 中的 else 语句…·
5.4 使用范围
第二篇 Python 进阶
第6章数据结构
6.1 元组
6.1.1 序列
6.1.2 创建元组
6.1.3 访问元组
6.1.4 遍历元组
6.2 列表
6.2.1 列表创建
6.2.2 追加元素
6.2.3插入元素
6.2.4替换元素
6.2.5 删除元素
6.2.6其他常用方法
6.2.7列表推导式
6.3集合
6.3.1创建可变集合
6.3.2修改可变集合
6.3.3 遍历集合
6.3.4 不可变集合
6.3.5 集合推导式
6.4 字典
6.1.1创建字典
6.1.2 修改字典
6.1.3 访问字典
6.1.4 遍历字典
6.1.5 字典推导式
第7章 函数式编程
7.1 定义函数
7.2 函数参数
7.2.1 使用关键字参数调用函数
7.2.2 参数默认值
7.2.3 可变参数
7.3 函数返回值
7.3.1 无返回值函数
7.3.2 多返回值函数
7.4 函数变量作用域
7.5 生成器
7.6 嵌套函数
7.7 函数式编程基础
7.7.1 函数类型
7.7.2 Lambda 表达式
7.7.3 三大基础函数

第8章 面向对象编程
8.1 面向对象概述
8.2 面向对象三个基本特性
8.2.1 封装性
8.2.2 继承性
8.2.3 多态性
8.3 类和对象
8.3.1 定义类
8.3.2 创建和使用对象
8.3.3 实例变量
8.3.4 类变量
8.3.5 构造方法
8.3.6 实例方法
8.3.7 类方法
8.3.8 静态方法
8.4 封装性
8.4.1私有变量
8.4.2私有方法
8.4.3定义属性
8.5 继承性
8.5.1继承概念
8.5.2重写方法 
8.5.3多继承
8.6 多态性
8.6.1 多态概念
8.6.2类型检查
8.6.3鸭子类型
8.7 Python 根类--object…
8.7.1_str_() 方法
8.7.2 对象比较方法
8.8 枚举类
8.8.1定义枚举类
8.8.2限制枚举类
8.8.3 使用枚举类
第 9 章 异常处理
9.1 异常问题举例
9.2 异常类继承层次
9.3 常见异常
9.3.1 AttributeError 异常
9.3.2 OSError 异常
9.3.3IndexError 异常
9.3.4 KeyError异常
9.3.5 NameError 异常
9.3.6 TypeError 异常
9.3.7 ValueError异常
9.4 捕获异常
9.4.1 try-except 语句
9.4.2 多 except 代码块
9.4.3 try-except 语句嵌套 
9.4.4 多重异常捕获
9.5 异常堆栈跟踪
9.6 释放资源
9.6.1 finally 代码块
9.6.2 else代码块
9.6.3 with as代码块自动资源管理
9.7 自定义异常类
9.8显式抛出异常
第10章 常用模块
10.1 math 模块 
10.1.1 舍入函数
10.1.2幂和对数函数
10.1.3 三角函数
10.2 random 模块 
10.3 datetime 模块
10.3.1 datetime、date 和 time 类
10.3.2 日期时间计算
10.3.3 日期时间格式化和解析
10.3.4 时区
10.4 logging 日志模块
10.4.1 日志级别
10.4.2 日志信息格式化
10.4.3 日志重定位 
10.4.4 使用配置文件
第11章 正则表达式
11.1 正则表达式字符串 
11.1.1 元字符
11.1.2 字符转义
11.1.3 开始与结束字符
11.2 字符类
11.2.1 发 定义字符类 
11.2.2 字符类取反 
11.2.3、区间 
11.2.4 预定义字符类
11.3 量词
11.3.1 量词的使用
11.3.2 贪婪量词和懒惰量词
11.4 分组
11.4.1 分组的使用
11.4.2 分组命名
11.4.3 反向引用分组
11.4.4 非捕获分组
11.5 re模块
11.5.1search()和match()函数
11.5.2 findall()和 finditer()函数
11.5.3 字符串分割
11.5.4 字符串替换
11.6 编译正则表达式
11.6.1 已编译正则表达式对象
11.6.2 编译标志
第 12 章 文件操作与管理
12.1 文件操作
12.1.1打开文件
12.1.2 关闭文件
12.1.3 文本文件读写
12.1.4 二进制文件读写 
12.2 os 模块 
12.3 os.path 模块



一、 Python 简介 Python 是一种高级编程语言,它是一种简单易学、功能强大的语言。Python 由 Guido van Rossum 在1989年底开始设计,第一个公开发行版发行于1991年。Python 被广泛用于各种领域,如网站开发、数据分析、人工智能等。Python 具有易读易写、模块化设计、动态类型、自动内存管理等特点。

二、 安装 Python 要使用 Python,需要先安装 Python 解释器。Python 的官方网站提供了各种操作系统的 Python 安装程序,可以在 https://www.python.org/downloads/ 上下载。

三、 Python 开发环境 Python 的开发环境有很多种,比较常用的有 IDLE、PyCharm、VS Code 等。在本教程中,我们将使用 IDLE 作为开发环境。

四、第一个 Python 程序 下面是一个简单的 Python 程序,它输出"Hello, world!"。

print("Hello, world!")

这个程序很简单,但它展示了 Python 的一些基本语法。print 函数用于输出文本,文本必须用引号括起来。在 Python 中,单引号和双引号都可以用来表示字符串。运行这个程序,可以看到"Hello, world!"被输出到屏幕上。

接下来,我们将逐步学习更多的 Python 语法和功能。


第1章 Python 语法基础

1.1 标识符和关键字

在编程语言中,标识符是指程序员定义的变量名、函数名等名称。而关键字是编程语言中已经预定义的,具有特殊含义的单词。

1.1.1 标识符

在 Python 中,标识符可以包含字母、数字、下划线,但不能以数字开头。例如,my_var、MY_VAR_1 都是合法的标识符。

标识符是用来标识变量、函数、类等名称的字符串。标识符的命名规则如下:

必须以字母或下划线 _ 开头。
可以包含任意多个字母、数字或下划线。
区分大小写。


以下是一个例子,演示如何使用标识符:

# 定义变量和函数
my_variable = 123
def my_function():
    print("This is my function.")

# 使用标识符
print(my_variable)
my_function()

输出结果为:

123
This is my function.


以下是一个简单的例子,定义一个变量并输出它的值:

my_var = "Hello, World!"
print(my_var)

输出结果为:

Hello, World!

1.1.2 关键字

Python 中有一些关键字是具有特殊含义的,不能用作变量名或函数名等标识符。

以下是 Python 中的一些关键字:

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

以下是一个例子,尝试使用关键字作为变量名:

 错误示例
 True = "Hello"
 print(True)

输出结果为:

File "<ipython-input-2-4d101c4f60d8>", line 1
    True = "Hello"
    ^SyntaxError: cannot assign to True


1.2 变量和常量

在 Python 中,变量是用来存储数据的容器,可以在程序执行过程中修改它的值。而常量是不可变的数据,一旦赋值就不能再修改。

变量是用来存储数据的标识符。在 Python 中,变量的类型是动态的,即在赋值时会自动确定类型。变量的命名规则和标识符的命名规则相同。

以下是一个例子,演示如何定义变量和使用变量:

1.2.1 变量

以下是一个例子,定义一个变量并输出它的值:

# 定义变量并赋值
my_variable = 123

# 使用变量
print(my_variable)

# 修改变量的值
my_variable = "Hello, World!"
print(my_variable)

输出结果为:

123
Hello, World!

1.2.2 常量

在 Python 中,可以使用关键字 const 来定义常量。但事实上,Python 中没有真正意义上的常量,只是通过约定俗成的方式来表示常量,即用全大写字母来表示一个变量是常量。

常量是在程序运行期间不会改变的值。在 Python 中,没有专门的常量类型,通常使用大写字母命名的变量来表示常量。

以下是一个例子,定义一个常量并输出它的值:

# 定义常量
PI = 3.14159

# 使用常量
print(PI)

# 修改常量的值(实际上是重新赋值一个变量,不是修改常量的值)
PI = 3.14
print(PI)

输出结果为:

3.14159
3.14

1.3 注释

在编程中,注释是用来解释代码的,不会被程序执行。在 Python 中,可以使用 # 号来表示单行注释,也可以使用三个引号 ''' 或 """ 来表示多行注释。

以下是一个例子,演示如何使用注释:

# 这是一个单行注释
'''
这是一个多行注释
可以在这里写多行注释
'''
"""
这也是一个多行注释
可以使用三个引号表示
"""

1.4 语句

在 Python 中,每行代码就是一条语句,可以使用分号 ; 来将多条语句放在同一行。但通常不建议这样做,因为这会使代码变得难以阅读。

以下是一个例子,演示如何使用语句:

print("Hello, World!")
print("This is a statement.")
# 以下是将两条语句放在同一行的示例
print("Hello, World!"); print("This is another statement.")

输出结果为:

Hello, World!
This is a statement.
Hello, World!
This is another statement.
# 定义变量并赋值
my_variable = 123

# 判断变量的值是否等于 123
if my_variable == 123:
    print("The value is 123.")

# 定义函数并调用
def my_function():
    print("This is my function.")

my_function()

输出结果为:

The value is 123.
This is my function.


1.5 模块

在 Python 中,模块是一个包含函数、变量、类等的文件。可以通过导入模块来使用其中的内容。

模块是包含 Python 代码的文件。在 Python 中,可以使用 import 语句将模块导入到当前程序中,并使用其中定义的变量、函数、类等。

以下是一个例子,演示如何导入模块并使用其中的函数:

# 导入 math 模块
import math
# 使用 math 模块中的函数
print(math.sqrt(16))

输出结果为:

4.0

以下是一个例子,演示如何使用模块:

假设有一个名为 my_module.py 的模块文件,内容如下:

# 定义变量和函数
my_variable = 123
def my_function():    
    print("This is my function.")

在另一个 Python 文件中,可以使用 import 语句将 my_module.py 导入,并使用其中定义的变量和函数:

# 导入模块
import my_module

# 使用模块中的变量和函数
print(my_module.my_variable)
my_module.my_function()

输出结果为:

123
This is my function.


1.6 包

包是一组相关的模块的集合。在 Python 中,包是一个目录,其中包含一个名为 init.py 的文件,用来表示该目录是一个包。可以通过导入包来使用其中的模块。

1.6.1 创建包

以下是一个例子,演示如何创建一个包和其中的模块:

# 在项目根目录下创建一个名为 my_package 的目录
# 在 my_package 目录下创建一个名为 my_module.py 的文件
# 在 my_module.py 文件中定义一个名为 my_func 的函数
def my_func():    
    print("This is my function.")

1.6.2 导入包

以下是一个例子,演示如何导入包和其中的模块:

# 导入 my_package 包和其中的 my_module 模块
from my_package import my_module

# 使用 my_module 模块中的函数
my_module.my_func()

输出结果为:

This is my function.

再举一个例子:

创建包

创建包需要在一个目录下创建多个 Python 文件,并使用 init.py 文件将它们组织起来。init.py 文件可以为空文件或包含初始化代码。

以下是一个例子,演示如何创建一个名为 my_package 的包:

my_package/
    __init__.py
    module1.py
    module2.py

其中,init.py 文件可以为空文件或包含初始化代码,例如:

# __init__.py

# 初始化代码
print("my_package is imported.")

导入包

导入包需要使用 import 语句,并指定包名和要导入的模块名。

以下是一个例子,演示如何导入 my_package 包中的 module1.py 模块:

# 导入 my_package 包中的 module1 模块
import my_package.module1

# 使用模块中定义的变量和函数
print(my_package.module1.my_variable)
my_package.module1.my_function()

输出结果为:

my_package is imported.
123
This is my function.
除了使用完整的模块名导入模块外,还可以使用 from ... import ... 语句导入模块中的特定内容。
以下是一个例子,演示如何导入 my_package 包中的 module2.py 模块中的 my_variable 变量:


# 导入 my_package 包中的 module2 模块中的 my_variable 变量
from my_package.module2 import my_variable

# 使用变量
print(my_variable)

输出结果为:

456


以上是 Python 语法基础的基本内容,可以让孩子们了解 Python 的基础语法,为后续的编程学习打下基础。


第2章 Python 编码规范

2.1 命名规范 在 Python 中,命名规范是非常重要的。遵循命名规范可以让你的代码更加易于阅读和理解。在 Python 中,命名规范如下:

  • 变量名和函数名应该使用小写字母,使用下划线来分隔单词。

  • 类名应该使用大写字母开头的驼峰命名法。

例如:

# 变量名和函数名
my_variable = 42
def my_function():
    pass

# 类名
class MyClass:
    pass


2.2 注释规范 在 Python 中,注释可以提高代码的可读性和可维护性。Python 支持多种注释方式,包括文件注释、文档注释、代码注释和 TODO 注释。

2.2.1 文件注释 在每个 Python 文件的开头,应该包含文件注释。文件注释应该描述该文件的用途,并提供作者、日期和版本等信息。例如

# my_module.py - A module for doing something useful.
#
# Author: Jane Doe
# Date: 2022-03-08
# Version: 1.0

# Code goes here...

2.2.2 文档注释 在 Python 中,文档注释是指在函数或类的定义中使用三个双引号来注释函数或类的用途、参数、返回值等信息。例如:

def my_function(param1, param2):
    """
    This is a description of my_function.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        The return value.
    """
    pass

2.2.3 代码注释 在代码中,应该使用注释来解释代码的用途和实现方式。注释应该简洁明了,不应该重复代码本身的含义。例如:

# Calculate the sum of two numbers.
sum = 1 + 2

2.2.4 使用 TODO 注释 在代码中,如果有未完成的任务或需要改进的地方,可以使用 TODO 注释来提醒自己或其他开发者。例如:

# TODO: Add error handling.
result = 1 / 0

2.3 导入规范 在 Python 中,应该尽可能在代码的开头导入所需的模块。导入应该按照以下顺序进行:

  1. Python 标准库模块

  2. 相关的第三方模块

  3. 本地应用/库特定的模块

例如:

import os
import sys

import requests

from my_module import MyClass

2.4 代码排版 在 Python 中,代码的排版也非常重要。遵循统一的排版规范可以提高代码的可读性和可维护性。

2.4.1 空行 在 Python 中,应该使用空行来分隔不同的代码块,以提高代码的可读性。例如:

# 前面的代码...

def my_function():
    # 函数体

class MyClass:
    # 类定义

# 后面的代码...

2.4.2 空格 在 Python 中,应该在运算符、逗号、冒号等字符前后加上空格,以提高代码的可读性。例如:

result = 1 + 2
my_list = [1, 2, 3]
for i in range(0, 10):
    # 循环体

2.4.3 缩进 在 Python 中,缩进是非常重要的。缩进用于表示代码块的层次结构。通常,每个缩进级别使用 4 个空格。例如:



if x > 0:
    # 条件成立的代码块
else:
    # 条件不成立的代码块

2.4.4 断行 在 Python 中,如果一行代码过长,可以使用括号或反斜杠来将其拆分成多行。

这样做有助于提高代码的可读性和可维护性。

例如,假设有一个很长的字符串,可以使用反斜杠将其拆分成多行:

long_string = "This is a very long string that " \\
              "spans multiple lines for readability."

同样的,如果有一个长的表达式,可以使用括号将其拆分成多行:

result = (some_long_variable + another_long_variable +
          yet_another_long_variable - one_more_long_variable)

这种方式的好处是,当代码需要修改时,不需要修改整个长字符串或长表达式,而只需要修改其中的一部分。


欢迎来到Python编程的世界!在本章中,我们将探讨Python中的不同数据类型以及它们之间的转换方法。我们将涵盖数字类型和字符串类型,这些是编程中最常见的数据类型之一。

第3章 数据类型

3.1 数字类型

数字类型在Python中非常重要,因为它们用于存储数值,执行算术运算,并与其他数据类型进行交互。Python中有几种数字类型,包括整数类型、浮点类型、复数类型和布尔类型。


3.1.1 整数类型

整数是没有小数部分的数字。在Python中,可以使用整数存储数字。以下是一些整数的例子:

num1 = 10
num2 = -25
num3 = 0


3.1.2 浮点类型

浮点数是带有小数部分的数字。在Python中,可以使用浮点数存储这些数字。以下是一些浮点数的例子:

num1 = 3.14
num2 = -2.5
num3 = 0.0


3.1.3 复数类型

复数是由实部和虚部组成的数字。在Python中,可以使用复数存储这些数字。以下是一些复数的例子:

num1 = 2 + 3j
num2 = -1 - 5j
num3 = 4j


3.1.4 布尔类型

布尔类型只有两个值:True和False。在Python中,可以使用布尔类型来表示逻辑值。以下是一些布尔类型的例子:

result1 = Trueresult2 = False


3.2 数字类型相互转换

Python中的数字类型可以相互转换,这在编程中非常有用。下面我们将介绍两种类型转换:隐式类型转换和显式类型转换。


3.2.1 隐式类型转换

隐式类型转换是Python自动执行的类型转换,以使得不同类型的数字能够执行算术运算。

例如,当我们将一个整数和一个浮点数相加时,Python会自动将整数转换为浮点数。以下是一个例子:

num1 = 10
num2 = 3.14
result = num1 + num2
print(result) # 输出结果为13.14,是一个浮点数


3.2.2 显式类型转换

显式类型转换是我们手动执行的类型转换,以将一个数字类型转换为另一个数字类型。以下是一些示例:

#将整数转换为浮点数
num1 = 10
num2 = float(num1)
print(num2) # 输出结果为10.0,是一个浮点数


#将浮点数转换为整数
num1 = 3.14
num2 = int(num1)
print(num2) # 输出结果为3,是一个整数


3.3 字符串类型字符串是一种非常重要的数据类型,因为它们用于表示文本信息。

在Python中,可以使用单引号或双引号来表示字符串。以下是一些字符串的例子:

#将整数转换为字符串
num1 = 123 
str1 = str(num1) 
print(str1) # 输出结果为"123",是一个字符串


#将字符串转换为整数
str1 = "456" 
num1 = int(str1) 
print(num1) # 输出结果为456,是一个整数


3.3.1 字符串表示方式在Python中,有几种方式可以表示字符串,

例如使用单引号或双引号,以及使用三引号('''或""")表示多行字符串。以下是一些示例:

str1 = "Hello, World!" # 使用双引号表示字符串
str2 = 'I love Python!' # 使用单引号表示字符串 
str3 = '''This is a multi-line string.''' # 使用三引号表示多行字符串


3.3.2 字符串格式化字符串格式化是一种在字符串中插入变量或值的方法。

在Python中,可以使用字符串格式化来创建动态字符串。以下是一些示例:

name = "Alice" 
age = 25 
message = "My name is {} and I am {} years old.".format(name, age) print(message) 
# 输出结果为"My name is Alice and I am 25 years old."


3.3.3 字符串查找在Python中,可以使用一些内置函数来查找字符串中的特定字符或子字符串。以下是一些示例:

str1 = "Hello, World!" 
index = str1.find("World") # 查找"World"子字符串的位置 
print(index) # 输出结果为7
str2 = "I love Python!"
result = "Python" in str2 # 检查字符串中是否包含"Python"子字符串 
print(result) # 输出结果为True


3.3.4 字符串与数字相互转换在Python中,可以使用一些函数将字符串转换为数字类型,

并将数字类型转换为字符串。以下是一些示例:

#将字符串转换为整数
str1 = "123" 
num1 = int(str1) 
print(num1) # 输出结果为123,是一个整数


#将字符串转换为浮点数
str1 = "3.14" 
num1 = float(str1) 
print(num1) # 输出结果为3.14,是一个浮点数


#将整数转换为字符串
num1 = 123 
str1 = str(num1) 
print(str1) # 输出结果为"123",是一个字符串


#将浮点数转换为字符串
num1 = 3.14 
str1 = str(num1) 
print(str1) # 输出结果为"3


第4章 运算符

4.1 算术运算符

算术运算符是用来进行数学运算的符号,常见的算术运算符有加法、减法、乘法和除法。


4.1.1 一元运算符

一元运算符只需要一个操作数。在Python中,唯一的一元运算符是负号(-),用来对数值进行取反。


下面是一个例子:

x = 10
y = -x
print(y)  # 输出结果为-10

4.1.2 二元运算符

二元运算符需要两个操作数。常见的二元运算符有加法(+)、减法(-)、乘法(*)、除法(/)和取模(%)。


下面是一个例子:

x = 10
y = 5
print(x + y)  # 输出结果为15
print(x - y)  # 输出结果为5
print(x * y)  # 输出结果为50
print(x / y)  # 输出结果为2.0
print(x % y)  # 输出结果为0

4.2 关系运算符

关系运算符用于比较两个值的大小或者是否相等。常见的关系运算符有等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)和小于等于(<=)。


下面是一个例子:

x = 10
y = 5
print(x == y)  # 输出结果为False
print(x != y)  # 输出结果为True
print(x > y)  # 输出结果为True
print(x < y)  # 输出结果为False
print(x >= y)  # 输出结果为True
print(x <= y)  # 输出结果为False

4.3 逻辑运算符

逻辑运算符用于对布尔值进行逻辑操作。常见的逻辑运算符有与(and)、或(or)和非(not)。


下面是一个例子:

x = True
y = False
print(x and y)  # 输出结果为False
print(x or y)  # 输出结果为True
print(not x)  # 输出结果为False

4.4 位运算符

位运算符用于对二进制数进行位操作。常见的位运算符有按位与(&)、按位或(|)、按位异或(^)和取反(~)。


下面是一个例子:

x = 10  # 十进制数10的二进制表示为1010
y = 5  # 十进制数5的二进制表示为0101
print(x & y)  # 输出结果为0,因为1010和0101按位与的结果是0000
print(x | y)
输出结果为15,因为1010和0101按位或的结果是1111

print(x ^ y) # 输出结果为15,因为1010和0101按位异或的结果是1111

print(~x) # 输出结果为-11,因为将1010取反得到0101,再将其转换为十进制数得到-11


4.5 赋值运算符


赋值运算符用于将值赋给变量。常见的赋值运算符有等于(=)、加等于(+=)、

减等于(-=)、乘等于(*=)、除等于(/=)和取模等于(%=)。


下面是一个例子:

x = 10
x += 5  # 等价于x = x + 5
print(x)  # 输出结果为15


4.6 其他运算符

除了上面介绍的运算符之外,Python还提供了其他的运算符,包括同一性测试运算符和成员测试运算符。


4.6.1 同一性测试运算符

同一性测试运算符用于比较两个对象是否是同一个对象,即它们是否具有相同的内存地址。


a = [1, 2, 3]
b = a


# 判断a和b是否是同一个对象
if a is b:
    print("a和b是同一个对象")
# 判断a和b是否不是同一个对象
if a is not b:
    print("a和b不是同一个对象")

4.6.2 成员测试运算符

成员测试运算符用于测试一个值是否是一个序列的成员。


a = [1, 2, 3]
# 判断1是否是a的成员
if 1 in a:
    print("1是a的成员")
# 判断4是否不是a的成员
if 4 not in a:
    print("4不是a的成员")

4.7 运算符优先级

当多个运算符同时出现时,Python将按照优先级顺序依次执行运算。以下是Python中运算符的优先级,从高到低:


括号和表达式
幂运算符(**)
正负号运算符(+x,-x)
乘法、除法、取模运算符(*,/,%)
加法、减法运算符(+,-)
左移、右移运算符(<<,>>)
位运算符(&,|,^)
比较运算符(==,!=,>,<,>=,<=)
布尔运算符(not,and,or)
同一性测试运算符(is,is not)
成员测试运算符(in,not in)
赋值运算符(=,+=,-=,*=,/=,//=,%=,**=,&=,|=,^=,<<=,>>=)

在编写代码时,应该尽量使用括号来明确运算的顺序,以免因为优先级问题导致错误的结果。


欢迎来到Python编程教程!在本章中,我们将学习Python中的控制语句,这些语句可以帮助我们控制程序的执行流程。掌握这些语句可以让你的程序更加灵活和强大。我们将按照以下目录来逐一介绍这些语句:


5.1 分支语句

5.1.1 if结构

if语句是Python中最基本的条件语句之一,它允许我们根据某个条件来决定程序的执行流程。下面是一个if语句的例子:


age = 10
if age < 18:
    print("You are not old enough to vote.")

这个例子中,我们定义了一个变量age,然后使用if语句来检查这个变量是否小于18。如果是,就输出一条消息来提醒用户他还不能投票。如果不是,程序就会跳过这个if语句,继续往下执行。


5.1.2 if-else 结构

if-else结构允许我们在满足条件时执行一组语句,在不满足条件时执行另一组语句。下面是一个if-else结构的例子:


age = 20
if age < 18:
    print("You are not old enough to vote.")
else:
    print("You are old enough to vote.")

这个例子中,如果年龄小于18,就输出一条消息提醒用户不能投票;否则,输出一条消息提醒用户可以投票。


5.1.3 elif结构

elif结构允许我们在满足多个条件时依次检查它们,执行第一个满足条件的语句块。下面是一个elif结构的例子:


age = 20
if age < 18:
    print("You are not old enough to vote.")
elif age < 21:
    print("You can vote, but not drink.")
else:
    print("You can vote and drink.")

这个例子中,如果年龄小于18,就输出一条消息提醒用户不能投票;如果年龄小于21,就输出一条消息提醒用户可以投票,但不能喝酒;否则,输出一条消息提醒用户可以投票和喝酒。


5.1.4 三元运算符替代品--条件表达式

Python还支持使用三元运算符作为if-else的替代品。下面是一个三元运算符的例子:


age = 20
status = "can vote" if age >= 18 else "cannot vote"
print(status)

这个例子中,如果年龄大于等于18,就将变量status设置为"can vote",否则设置为"cannot vote",然后输出变量status的值。


5.2 循环语句

循环语句允许我们重复执行一段代码,直到满足某个条件为止。Python中有两种循环语句:while循环和for循环。


5.2.1 while 语句

while语句允许我们在满足条件时重复执行一组语句。下面是一个while循环的例子:


count = 0
while count < 5:
    print(count)
    count += 1

这个例子中,我们定义了一个变量count,并使用while循环来检查这个变量是否小于5。只要满足条件,就输出变量count的值,并将变量count加1。循环将一直执行,直到变量count的值不再小于5为止。


5.2.2 for 语句

for语句允许我们遍历一个序列(比如列表或元组)中的每个元素,并对其执行相同的操作。下面是一个for循环的例子:


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

这个例子中,我们定义了一个列表fruits,并使用for循环来遍历这个列表中的每个元素。在每次循环中,变量fruit将被赋值为当前元素的值,然后输出变量fruit的值。


5.3 跳转语句

跳转语句允许我们在循环中控制程序的执行流程。Python中有三种跳转语句:break、continue和else。


5.3.1 break 语句

break语句允许我们在循环中提前结束循环。下面是一个使用break语句的例子:


count = 0
while True:
    print(count)
    count += 1
    if count >= 5:
        break

这个例子中,我们使用了一个while循环来无限输出变量count的值。然而,如果变量count的值达到了5,就使用break语句来提前结束循环。


5.3.2 continue 语句

continue语句允许我们在循环中跳过当前的迭代,直接进入下一次迭代。下面是一个使用continue语句的例子:


count = 0
while count < 5:
    count += 1
    if count == 3:
        continue
    print(count)

这个例子中,我们使用了一个while循环来输出变量count的值。然而,如果变量count的值等于3,就使用continue语句来跳过这次循环,直接进入下一次循环。


5.3.3 while 和 for 中的 else 语句

while和for循环还支持使用else语句,用于在循环正常结束时执行一些操作。如果循环中使用了break语句,else语句将不会被执行。下面是一个使用while循环和else语句的例子:


count = 0
while count < 5:
    print(count)
    count += 1
else:
    print("Loop is finished")

这个例子中,我们使用了一个while循环来输出变量count的值。当循环正常结束时,将输出一条消息“Loop is finished”。


下面是一个使用for循环和else语句的例子:


fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
else:
    print("Loop is finished")

这个例子中,我们使用了一个for循环来遍历列表fruits中的每个元素。当循环正常结束时,将输出一条消息“Loop is finished”。


5.4 使用范围

掌握好控制语句和循环语句,可以让我们更好地控制程序的执行流程。在编写复杂的程序时,我们通常会用到这些语句,以实现不同的功能。


除了编写程序,掌握好这些语句还可以让我们更好地理解其他人编写的程序。在学习Python编程的过程中,我们可以尝试阅读其他人编写的代码,并思考其中控制语句和循环语句的作用,以提高自己的编程能力。


另外,掌握好控制语句和循环语句也可以让我们更好地解决问题。例如,当我们需要对一个数据集进行处理时,可能需要使用循环语句来遍历数据集中的每个元素,并使用条件语句来筛选出符合要求的数据。


此外,掌握好这些语句还可以让我们更好地理解计算机科学中的一些基本概念,例如算法和数据结构。在算法和数据结构中,控制语句和循环语句是非常重要的概念,它们可以帮助我们设计和实现高效的算法和数据结构。


总之,掌握好控制语句和循环语句是Python编程中非常重要的一部分。通过学习和练习,我们可以更好地控制程序的执行流程,解决问题,以及理解计算机科学中的基本概念。


欢迎来到Python编程教程第六章,本章将介绍Python中的数据结构。数据结构是计算机程序设计中的重要概念,可以帮助我们在程序中组织和管理数据。在本章中,我们将介绍Python中的四种基本数据结构:元组、列表、集合和字典。我们将详细讲解每种数据结构的创建、修改和遍历,同时提供具体的数据示例和编程示例,帮助孩子更好地理解和掌握这些概念。


6.1 元组

元组是一种不可变的序列,可以存储任意类型的数据。在Python中,元组用小括号()来表示。


6.1.1 序列

序列是Python中最基本的数据结构之一。它是一个有序的数据集合,可以存储多个元素,并且每个元素可以通过索引访问。


6.1.2 创建元组

我们可以使用逗号分隔的多个值来创建元组。例如:



# 创建一个元组
t = (1, 2, 3, 4, 5)
print(t)

输出结果为:

(1, 2, 3, 4, 5)


6.1.3 访问元组

我们可以通过索引来访问元组中的元素。元组的索引从0开始,因此第一个元素的索引为0,第二个元素的索引为1,以此类推。


# 访问元组中的元素
t = (1, 2, 3, 4, 5)
print(t[0])  # 输出结果为1
print(t[1])  # 输出结果为2


6.1.4 遍历元组

我们可以使用for循环来遍历元组中的所有元素。


# 遍历元组中的元素
t = (1, 2, 3, 4, 5)
for i in t:
    print(i)

输出结果为:


1
2
3
4
5


6.2 列表

列表是Python中最常用的数据结构之一。它是一个有序的数据集合,可以存储多个元素,并且每个元素可以通过索引访问。列表是可变的,可以添加、删除、替换和插入元素。


6.2.1 列表创建

我们可以使用方括号[]来创建一个列表,并将多个元素用逗号分隔。例如:


# 创建一个列表
l = [1, 2, 3, 4, 5]
print(l)

输出结果为:

[1, 2, 3, 4, 5]


6.2.2 追加元素

我们可以使用append()方法来向列表中添加一个元素。


# 向列表
l = [1, 2, 3, 4, 5]
l.append(6)
print(l)


输出结果为:

[1, 2, 3, 4, 5, 6]



6.2.3 插入元素


我们可以使用insert()方法来向列表中插入一个元素,插入位置可以通过索引指定。


#向列表中插入一个元素
l = [1, 2, 3, 4, 5]
l.insert(2, 10)
print(l)


输出结果为:

[1, 2, 10, 3, 4, 5]


6.2.4 替换元素


我们可以直接通过索引来替换列表中的元素。


#替换列表中的一个元素
l = [1, 2, 3, 4, 5]
l[2] = 10
print(l)


输出结果为:

[1, 2, 10, 4, 5]


6.2.5 删除元素


我们可以使用del语句来删除列表中的一个元素。


#删除列表中的一个元素
l = [1, 2, 3, 4, 5]
del l[2]
print(l)

输出结果为:

[1, 2, 4, 5]


6.2.6 其他常用方法


Python中还有许多其他的列表方法,例如:


- extend()方法:向列表中添加另一个列表的元素。
- pop()方法:从列表中删除一个元素,并返回该元素的值。
- remove()方法:从列表中删除指定的元素。
- sort()方法:对列表中的元素进行排序。


6.2.7 列表推导式


列表推导式是一种快速创建列表的方式,它可以使用一行简单的代码来创建列表。


#使用列表推导式创建一个列表
l = [i**2 for i in range(1, 6)]
print(l)


输出结果为:

[1, 4, 9, 16, 25]



6.3 集合


集合是一种无序的数据集合,其中每个元素都是唯一的。集合是可变的,可以添加、删除和修改元素。在Python中,集合用花括号{}来表示。


6.3.1 创建可变集合


我们可以使用花括号{}或set()函数来创建一个集合。注意,如果使用花括号创建集合时,需要在花括号中至少包含一个元素。


#创建一个集合
s = {1, 2, 3, 4, 5}
print(s)


#使用set()函数创建一个集合
s = set([1, 2, 3, 4, 5])
print(s)

输出结果为:


{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}


6.3.2 修改可变集合

我们可以使用add()方法向集合中添加一个元素。


# 向集合中添加一个元素
s = {1, 2, 3, 4, 5}
s.add(6)
print(s)

输出结果为:

{1, 2, 3, 4, 5, 6}

我们也可以使用update()方法向集合中添加多个元素。


# 向集合中添加多个元素
s = {1, 2, 3, 4, 5}
s.update({6, 7, 8})
print(s)


输出结果为:

{1, 2, 3, 4, 5, 6, 7, 8}

我们可以使用remove()方法删除集合中的一个元素。


# 删除集合中的一个元素
s = {1, 2, 3, 4, 5}
s.remove(3)
print(s)


输出结果为:

{1, 2, 4, 5}


6.3.3 遍历集合

我们可以使用for循环来遍历集合中的所有元素。


# 遍历集合中的所有元素
s = {1, 2, 3, 4, 5}
for x in s:
    print(x)

输出结果为:


1
2
3
4
5


6.3.4 不可变集合

Python中的集合有两种类型:可变集合和不可变集合。不可变集合在创建后不能被修改,而可变集合可以被修改。不可变集合的创建方法与可变集合相同,只是在创建后不能再进行修改。


我们可以使用frozenset()函数来创建一个不可变集合。


# 创建一个不可变集合
s = frozenset([1, 2, 3, 4, 5])
print(s)

输出结果为:

frozenset({1, 2, 3, 4, 5})


6.3.5 集合推导式

集合推导式是一种快速创建集合的方式,它可以使用一行简单的代码来创建集合。


# 使用集合推导式创建一个集合
s = {i**2 for i in range(1, 6)}
print(s)

输出结果为:

{1, 4, 9, 16, 25}

6.4 字典

字典是一种无序的数据集合,其中每个元素都是由键和值组成的。字典是可变的,可以添加、删除和修改元素。在Python中,字典用花括号{}来表示,键和值之间用冒号:分隔。


6.4.1 创建字典

我们可以使用花括号{}或dict()函数来创建一个字典。字典中的元素是无序的,每个元素由一个键和一个值组成,键和值之间用冒号:分隔,每个元素之间用逗号,分隔。


# 创建一个字典
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
print(d)


# 使用dict()函数创建一个字典
d = dict(name='Bob', age=20, gender='male')
print(d)

输出结果为:


{'name': 'Alice', 'age': 18, 'gender': 'female'}
{'name': 'Bob', 'age': 20, 'gender': 'male'}


6.4.2 修改字典

我们可以通过索引访问字典中的值,并可以通过赋值语句修改字典中的值。


# 修改字典中的值
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
d['age'] = 20
print(d)

输出结果为:

{'name': 'Alice', 'age': 20, 'gender': 'female'}

我们可以使用update()方法向字典中添加新的键值对。


# 向字典中添加新的键值对
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
d.update({'grade': 90})
print(d)

输出结果为:

{'name': 'Alice', 'age': 18, 'gender': 'female', 'grade': 90}

6.4.3 访问字典

我们可以通过键来访问字典中的值。


# 访问字典中的值
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
print(d['name'])

输出结果为:

Alice

如果键不存在,会抛出KeyError异常。


# 访问不存在的键
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
print(d['score'])

输出结果为:


vbnet
KeyError: 'score'

我们可以使用get()方法来避免KeyError异常的发生。


# 使用get()方法访问不存在的键
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
print(d.get('score'))

输出结果为:

None

如果键不存在,get()方法会返回None。


6.4.4 遍历字典

我们可以使用for循环遍历字典中的所有键值对。


# 遍历字典中的所有键值对
d = {'name': 'Alice', 'age': 18, 'gender': 'female'}
for key, value in d.items():
    print(key, value)

输出结果为:


name Alice
age 18
gender female

6.4.5 字典推导式

字典推导式是一种快速创建字典的方式,它可以使用一行简单的代码来创建字典。


# 使用字典推导式创建一个字典
d = {i: i**2 for i in range(1, 6)}
print(d)


输出结果为:

{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

字典推导式的语法为:

{key_expression: value_expression for expression in iterable}

其中,key_expression和value_expression分别是键和值的表达式,expression是可迭代对象中的元素。


7.总结

本章介绍了Python中的常见数据结构,包括元组、列表、集合和字典。元组是不可变的序列,列表是可变的序列,集合是无序不重复元素的集合,字典是键值对的集合。我们学习了它们的创建、访问、修改、遍历和推导式等操作,希望能够为大家在实际编程中使用这些数据结构提供帮助。


欢迎来到Python编程学习之旅!在本章中,我们将学习函数式编程。函数是一种非常有用的编程结构,允许同学们编写可重用的代码,提高代码的可读性和可维护性。让我们来开始吧!


7.1 定义函数

函数是一种可以被多次调用的代码块。定义函数时,同学们可以指定函数的名称、参数和代码块。让我们看一个简单的例子:


def greet():
    print("Hello, World!")

在上面的代码中,我们定义了一个名为“greet”的函数,该函数不接受任何参数。该函数的代码块仅包含一条语句,该语句会打印“Hello, World!”到屏幕上。我们可以通过调用这个函数来执行这段代码块:

greet()

这将输出“Hello, World!”到屏幕上。


7.2 函数参数

在Python中,同学们可以在函数定义中指定参数。这些参数允许同学们将值传递给函数,以便在函数内部进行处理。让我们来看一些例子。


7.2.1 使用关键字参数调用函数

关键字参数允许同学们在调用函数时指定参数的名称和值。这使得函数调用更加清晰和易于理解。例如,我们可以重新定义我们的greet函数,并将其接受一个参数:


def greet(name):
    print("Hello, " + name + "!")

在这个例子中,我们将函数greet改为接受一个参数name。该函数将在打印“Hello, ”时使用该参数。我们可以使用关键字参数调用函数greet,如下所示:

greet(name="Alice")

这将输出“Hello, Alice!”到屏幕上。


7.2.2 参数默认值

默认参数值允许同学们为函数参数指定默认值。如果调用函数时未指定参数的值,则将使用该默认值。例如,我们可以重新定义我们的greet函数,将其设置一个默认参数值:


def greet(name="World"):
    print("Hello, " + name + "!")

在这个例子中,我们将函数greet改为使用一个默认参数值“World”。如果我们在调用greet时未指定参数,则将使用该默认值:

greet()

这将输出“Hello, World!”到屏幕上。我们还可以使用关键字参数来指定不同的值:

greet(name="Alice")

这将输出“Hello, Alice!”到屏幕上。


7.2.3 可变参数

可变参数允许同学们在调用函数时传递任意数量的参数。在函数定义中,同学们可以使用星号(*)来指定可变参数。例如,我们可以重新定义我们的greet函数,使其接受一个可变参数:


def greet(*names):
    for name in names:
        print("Hello, " + name + "!")


在这个例子中,我们使用星号(*)来指定参数names是可变的。我们可以通过使用逗号将多个参数传递给函数greet,例如:

greet("Alice", "Bob", "Charlie")

这将输出“Hello, Alice! Hello, Bob! Hello, Charlie!”到屏幕上。


7.3 函数返回值

在Python中,函数可以返回值。这些返回值可以是任何类型的数据,例如数字、字符串、列表、元组或字典。同学们可以使用关键字return来指定要返回的值。让我们来看一些例子。


7.3.1 无返回值函数

有些函数不需要返回值。例如,我们可以重新定义我们的greet函数,使其不返回任何值:


def greet(name):
    print("Hello, " + name + "!")

在这个例子中,我们省略了return语句,使函数greet不返回任何值。


7.3.2 多返回值函数

有些函数可以返回多个值。在Python中,同学们可以使用逗号将多个值分隔开来返回。例如,我们可以定义一个函数,返回两个数字的和和差:


def add_subtract(x, y):
    return x+y, x-y

在这个例子中,我们定义了一个函数add_subtract,该函数接受两个参数x和y。该函数返回两个值,它们是x+y和x-y的结果。我们可以使用两个变量来接收这两个返回值:


sum, diff = add_subtract(5, 3)
print(sum)  # 输出 8
print(diff)  # 输出 2

7.4 函数变量作用域

变量作用域指的是变量在程序中的可见性。在Python中,函数可以访问全局变量和局部变量。全局变量是定义在函数外部的变量,局部变量是定义在函数内部的变量。如果函数内部定义了一个局部变量和一个全局变量具有相同的名称,则函数将使用局部变量。


例如,我们可以定义一个全局变量和一个函数,该函数使用相同名称的局部变量:


x = 10
def print_x():
    x = 5
    print(x)
print_x()  # 输出 5
print(x)  # 输出 10

在这个例子中,我们定义了一个全局变量x和一个函数print_x。在函数print_x中,我们定义了一个局部变量x,该变量的值为5。当我们调用函数print_x时,它将打印局部变量x的值5。但是,全局变量x的值仍然为10。


7.5 生成器

生成器是一种特殊的函数,它可以在需要时生成值,而不是一次性生成所有值。在Python中,生成器使用yield语句来生成值。例如,我们可以定义一个生成器函数,用于生成斐波那契数列:


def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b


在这个例子中,我们定义了一个生成器函数fibonacci,该函数使用yield语句来生成斐波那契数列。在每次调用yield时,函数将生成下一个斐波那契数。我们可以使用for循环来迭代生成器:


fib = fibonacci()
for i in range(10):
    print(next(fib))


这将打印斐波那契数列的前10个数字。


7.6 嵌套函数

在Python中,函数可以嵌套在其他函数中。嵌套函数可以访问外部函数的变量和参数,例如:


def outer_function(x):
    def inner_function(y):
        return x + y
   return inner_function
add_five = outer_function(5)
print(add_five(3)) # 输出 8



在这个例子中,我们定义了一个外部函数outer_function,该函数接受一个参数x,并返回一个内部函数inner_function。内部函数inner_function接受一个参数y,并返回x + y的结果。我们可以使用外部函数outer_function来创建一个新的函数add_five,该函数使用x = 5,并将其传递给外部函数。我们可以使用add_five来计算5 + 3的结果。


7.7 函数式编程基础

函数式编程是一种编程范式,它将计算视为函数的应用,而不是一系列指令的执行。在Python中,函数式编程可以使用Lambda表达式和三大基础函数map、filter和reduce来实现。


7.7.1 函数类型

在Python中,函数是第一类对象,这意味着函数可以作为参数传递给其他函数,也可以从其他函数返回。例如,我们可以定义一个函数,该函数接受另一个函数作为参数:


def apply_twice(func, arg):
    return func(func(arg))
def add_five(x):
    return x + 5
print(apply_twice(add_five, 10)) # 输出 20



在这个例子中,我们定义了一个函数apply_twice,该函数接受两个参数:一个函数和一个参数。该函数将参数应用于给定的函数两次。我们还定义了一个函数add_five,该函数接受一个数字,并返回该数字加上5的结果。我们将add_five和10作为参数传递给apply_twice,并将其打印到屏幕上。


7.7.2 Lambda 表达式

Lambda表达式是一种匿名函数,可以在需要函数的任何地方定义。Lambda表达式可以用于编写简短的、一次性的函数。Lambda表达式的语法为:


lambda arguments: expression


例如,我们可以使用Lambda表达式来定义一个函数,该函数将给定的数字加上5:


add_five = lambda x: x + 5
print(add_five(10)) # 输出 15


在这个例子中,我们使用Lambda表达式定义了一个函数,该函数接受一个参数x,并返回x + 5的结果。我们将10传递给add_five函数,并将其打印到屏幕上。


7.7.3 三大基础函数

在函数式编程中,三大基础函数map、filter和reduce非常常用。它们可以帮助我们处理序列中的元素,并生成新的序列。下面是这三个函数的详细介绍。


7.7.3.1 map函数

map函数将一个函数应用于序列中的每个元素,并返回一个新的序列。例如,我们可以使用map函数将一个列表中的所有元素都平方:


numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares)  # 输出 [1, 4, 9, 16, 25]

在这个例子中,我们使用map函数将一个Lambda表达式应用于numbers列表中的每个元素。Lambda表达式将每个元素都平方,并将结果作为一个新列表返回。


7.7.3.2 filter函数

filter函数将一个函数应用于序列中的每个元素,并返回一个新的序列,其中只包含函数返回True的元素。例如,我们可以使用filter函数来筛选一个列表中的偶数:


numbers = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出 [2, 4]

在这个例子中,我们使用filter函数将一个Lambda表达式应用于numbers列表中的每个元素。Lambda表达式返回True,如果该元素是偶数,并将结果作为一个新列表返回。


7.7.3.3 reduce函数

reduce函数将一个函数应用于序列中的每对相邻元素,并返回一个单一的值。例如,我们可以使用reduce函数来计算一个列表中所有元素的总和:


from functools import reduce
numbers = [1, 2, 3, 4, 5]
sum = reduce(lambda x, y: x + y, numbers)
print(sum)  # 输出 15

在这个例子中,我们使用reduce函数将一个Lambda表达式应用于numbers列表中的每对相邻元素。Lambda表达式将相邻元素相加,并将结果作为单个值返回。reduce函数将该函数应用于所有元素,直到只剩下一个值。


到此为止,我们已经介绍了Python函数式编程的基础知识。函数式编程可以帮助我们编写更简洁、可重复使用的代码,同时还可以帮助我们更好地理解计算的本质。


完整代码示例:


# 7.1 定义函数
def greet(name):
    print("Hello, " + name + "!")
# 7.2 函数参数
# 7.2.1 使用关键字参数调用函数
def describe_pet(name, animal_type):
    print("I have a " + animal_type + ".")
    print("Its name is " + name + ".")
describe_pet(name="Tom", animal_type="cat")
# 7.2.2 参数默认值
def describe_pet(name, animal_type="dog"):
    print("I have a " + animal_type + ".")
    print("Its name is " + name + ".")
describe_pet(name="Tom")
describe_pet(name="Jerry", animal_type="mouse")
# 7.2.3 可变参数
def make_pizza(*toppings):
    print("Making a pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)
make_pizza("pepperoni")
make_pizza("mushrooms", "green peppers", "extra cheese")
# 7.3 函数返回值
# 7.3.1 无返回值函数
def greet(name):
    print("Hello, " + name + "!")
# 7.3.2 多返回值函数
def square_and_cube(number):
    return number**2, number**3
square, cube = square_and_cube(3)
print(square)  # 输出 9
print(cube)  # 输出 27
# 7.4 函数变量作用域
def spam():
    eggs = 99  # 局部变量
    bacon()
def bacon():
    ham = 101  # 局部变量
    eggs = 0  # 局部变量
# 7.5 生成器
def countdown(n):
    while n > 0:
        yield n
        n -= 1
for i in countdown(5):
    print(i)  # 输出 5 4 3 2 1
# 7.6 嵌套函数
def outer():
    x = 1
    def inner():
        print(x)
    inner()
outer()  # 输出 1
# 7.7 函数式编程基础
# 7.7.1 函数类型
def add_five(x):
    return x + 5
print(add_five(10))  # 输出 15
# 7.7.2 Lambda 表达式
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares)  # 输出 [1, 4, 9, 16, 25]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出 [2, 4]
from functools import reduce
sum = reduce(lambda x, y: x + y, numbers)
print(sum)  # 输出 15

希望这份Python函数式编程教程能够对同学们有所帮助!


第8章 面向对象编程


在本章中,我们将学习面向对象编程的基础知识,包括面向对象的概述和三个基本特性:封装性、继承性和多态性。我们将深入了解类和对象,并了解类变量、实例变量、构造方法、实例方法、类方法和静态方法等概念。我们还将探讨封装性、继承性和多态性的更多细节,以及如何使用Python中的object类和枚举类。


8.1 面向对象概述


面向对象编程(Object-Oriented Programming,OOP)是一种编程方法,其中程序的主要构建块是对象。对象是类的实例,类是一种表示对象的模板。OOP的主要目的是通过在程序中创建对象来模拟现实世界中的事物。


8.2 面向对象三个基本特性


面向对象编程有三个基本特性,它们是封装性、继承性和多态性。


8.2.1 封装性


封装性是指将数据和代码保护起来,防止其他代码意外更改或错误地使用它们。在面向对象编程中,可以使用访问控制来实现封装性,例如私有变量和私有方法。


8.2.2 继承性


继承性是指创建一个新的类来继承另一个类的属性和方法。被继承的类称为父类或超类,新类称为子类或派生类。子类可以重写父类的方法,也可以添加自己的属性和方法。


8.2.3 多态性


多态性是指同一个方法名可以在不同的类中有不同的实现方式。多态性允许不同的对象对同一个方法做出不同的响应。


8.3 类和对象


在Python中,我们可以通过定义类和创建对象来实现面向对象编程。


8.3.1 定义类


定义类需要使用class关键字,然后在冒号后面定义类的属性和方法。


class MyClass:
    # 类属性
    class_variable = "Hello, World!"
    
    # 构造方法
    def __init__(self, arg1, arg2):
        # 实例属性
        self.instance_variable1 = arg1
        self.instance_variable2 = arg2
        
    # 实例方法
    def instance_method(self):
        print("This is an instance method.")
        
    # 类方法
    @classmethod
    def class_method(cls):
        print("This is a class method.")
        
    # 静态方法
    @staticmethod
    def static_method():
        print("This is a static method.")

8.3.2 创建和使用对象


创建对象需要使用类名和括号,括号中可以传递构造方法中需要的参数。


# 创建对象
my_object = MyClass("arg1_value", "arg2_value")

使用对象的属性和方法

print(my_object.instance_variable1)
my_object.instance_method()
MyClass.class_method()
MyClass.static_method()



8.3.3 实例变量


实例变量是属于类的每个对象的属性,它们可以通过self关键字在构造方法或实例方法中设置或获取。


class MyClass:
    def __init__(self, arg1, arg2):
        # 设置实例变量
        self.instance_variable1 = arg1
        self.instance_variable2 = arg2
        
    def instance_method(self):
        # 获取实例变量
        print(self.instance_variable1)

8.3.4 类变量


类变量是属于类的所有对象的属性,它们可以通过类名或实例对象访问。


class MyClass:
    # 定义类变量
    class_variable = "Hello, World!"
    
    def __init__(self, arg1, arg2):
        # 设置实例变量
        self.instance_variable1 = arg1
        self.instance_variable2 = arg2
        
    def instance_method(self):
        # 获取类变量
        print(MyClass.class_variable)
        print(self.class_variable) # 也可以通过实例对象访问

8.3.5 构造方法


构造方法是一个特殊的方法,用于在创建对象时初始化对象的属性。在Python中,构造方法的名称始终为__init__,第一个参数是self,它表示正在初始化的对象本身,其他参数是构造方法所需的参数。


class MyClass:
    def __init__(self, arg1, arg2):
        self.instance_variable1 = arg1
        self.instance_variable2 = arg2

8.3.6 实例方法


实例方法是属于对象的方法,它们可以通过self关键字在类中定义和使用。


class MyClass:
    def instance_method(self, arg):
        print("This is an instance method. The argument is:", arg)

8.3.7 类方法


类方法是属于类的方法,它们可以通过装饰器@classmethod在类中定义和使用,第一个参数是cls,它表示正在使用方法的类本身。


class MyClass:
    @classmethod
    def class_method(cls, arg):
        print("This is a class method. The argument is:", arg)

8.3.8 静态方法


静态方法不属于任何对象或类,它们可以通过装饰器@staticmethod在类中定义和使用。


class MyClass:
    @staticmethod
    def static_method(arg):
        print("This is a static method. The argument is:", arg)

8.4 封装性


封装性是通过访问控制来实现的,Python使用下划线(_)表示属性或方法的可见性。


8.4.1 私有变量


私有变量是只能在类内部访问的变量,它们以两个下划线(__)开头。在Python中,私有变量实际上是通过将变量名重命名为一个以“_类名__变量名”的形式实现的。


class MyClass:
    def __init__(self, arg):
        self.__private_variable = arg # 定义私有变量
    
    def __private_method(self):
        print("This is a private method.")

在类外部,可以通过使用“_类名__变量名”来访问私有变量。


my_object = MyClass("Hello, World!")
print(my_object._MyClass__private_variable) # 访问私有变量


8.4.2 私有方法


私有方法是只能在类内部访问的方法,它们以两个下划线(__)开头。在Python中,私有方法实际上是通过将方法名重命名为一个以“_类名__方法名”的形式实现的。


class MyClass:
    def __private_method(self):
        print("This is a private method.")


8.4.3 定义属性


Python还提供了一种更简单的方式来控制属性的访问,即使用@property装饰器定义属性。通过定义属性的getter和setter方法,可以控制属性的读取和写入。属性的getter方法用@property装饰器标记,属性的setter方法用@property装饰器的名字.setter标记。


class MyClass:
    def __init__(self, arg):
        self._variable = arg # 定义属性
    
    @property
    def variable(self):
        print("Getting the value of variable.")
        return self._variable
    
    @variable.setter
    def variable(self, arg):
        print("Setting the value of variable.")
        self._variable = arg

在这个例子中,我们定义了一个名为variable的属性,它可以通过getter和setter方法访问和修改。使用@property装饰器可以使属性的访问更加直观和方便。


my_object = MyClass("Hello, World!")
print(my_object.variable) # 获取属性的值
my_object.variable = "Hello, Python!" # 设置属性的值
print(my_object.variable) # 获取属性的新值


8.5 继承性


继承性是面向对象编程中的一个重要特性,它允许创建一个新类,该类继承了现有类的属性和方法,并且可以添加自己的属性和方法。


8.5.1 继承概念


继承是通过将现有类作为新类的基类来实现的。新类从基类中继承了属性和方法,并且可以添加自己的属性和方法。


class MyBaseClass:
    def base_method(self):
        print("This is a base method.")
        
class MyDerivedClass(MyBaseClass): # 继承基类
    def derived_method(self):
        print("This is a derived method.")

在这个例子中,MyDerivedClass继承了MyBaseClass,可以使用它的方法base_method,也可以添加自己的方法derived_method。


my_object = MyDerivedClass()
my_object.base_method() # 调用继承的方法
my_object.derived_method()


8.6 多态性


8.6.1 多态概念


多态是指不同对象对同一方法的调用可以产生不同的结果,即同一操作作用于不同对象上面时,可以产生不同的执行结果。

多态是面向对象编程的重要概念,指同一种行为具有多种实现方式或形态的能力。在Python中,多态可以通过继承和重写方法来实现。当子类重写父类的方法时,如果在父类中调用该方法,实际上执行的是子类的方法。


例如,对于一个基类 Animal 和其子类 Cat、Dog,它们都可以有一个 make_sound() 方法来发出声音,但 Cat 和 Dog 的叫声是不同的。这时,我们可以在不知道对象具体类型的情况下调用这个方法,并且根据对象的实际类型来执行相应的方法。


下面是一个例子,我们定义了一个 Animal 类和其子类 Cat 和 Dog,它们都有一个 make_sound() 方法来发出声音:


class Animal:
    def make_sound(self):
        pass
class Cat(Animal):
    def make_sound(self):
        print("喵喵喵")
class Dog(Animal):
    def make_sound(self):
        print("汪汪汪")
def animal_sound(animal):
    animal.make_sound()
cat = Cat()
dog = Dog()
animal_sound(cat) # 输出 "喵喵喵"
animal_sound(dog) # 输出 "汪汪汪"


在上面的例子中,我们定义了一个 animal_sound() 函数来输出动物发出的声音。这个函数的参数是一个 Animal 对象,但是它可以接受任何 Animal 的子类对象作为参数。在函数内部,我们调用了传入对象的 make_sound() 方法来发出声音。


当我们传入一个 Cat 对象时,它调用了 Cat 类的 make_sound() 方法,输出了 "喵喵喵";当我们传入一个 Dog 对象时,它调用了 Dog 类的 make_sound() 方法,输出了 "汪汪汪"。这就是多态的体现。


8.6.2类型检查


在多态的使用过程中,我们可能会需要判断对象的类型。Python 提供了一些内置函数来进行类型检查,包括 isinstance() 函数和 type() 函数。


isinstance() 函数用于判断一个对象是否是某个类或其子类的实例,其语法格式如下:

isinstance(object, classinfo)

其中,object 表示要判断的对象,classinfo 表示要判断的类或类型。如果 object 是 classinfo 的实例,或者是其子类的实例,则返回 True;否则返回 False。


下面是一个例子,我们定义了一个 Animal 类和其子类 Cat 和 Dog,然后使用 isinstance() 函数来判断对象的类型:


class Animal:
    pass
class Cat(Animal):
    pass
class Dog(Animal):
    pass
cat = Cat()
dog = Dog()
print(isinstance(cat, Cat)) # 输出 True
print(isinstance(cat, Animal)) # 输出 True
print(isinstance(dog, Dog)) # 输出 True
print(isinstance(dog, Animal)) # 输出 True
print(isinstance(cat, Dog)) # 输出 False

在上面的例子中,我们分别创建了一个 Cat 对象和一个 Dog 对象,并使用 isinstance() 函数来判断它们的类型。


8.6.3 鸭子类型


鸭子类型是一种动态类型,它是Python中多态的一种形式。它的含义是,只要一个对象具有特定的方法或属性,就可以在代码中将其视为特定类型的对象。


例如,如果我们有一个eat()方法,我们可以将任何具有eat()方法的对象视为Animal类的对象。这种做法可以让我们在不需要继承的情况下实现多态。


class Duck:
    def eat(self):
        print("Duck is eating bread")
def feed(animal):
    animal.eat()
cat = Cat()
dog = Dog()
duck = Duck()
feed(cat)
feed(dog)
feed(duck)

输出结果:


Cat is eating fish
Dog is eating meat
Duck is eating bread

我们可以看到,feed()方法接受任何具有eat()方法的对象作为参数,无需关心它们的具体类型。这就是鸭子类型的优势。



8.7 Python 根类--object


在Python中,所有类都直接或间接地继承自一个叫做object的类。因此,我们在定义类时可以省略继承自object。


Python中所有的类都是从object类继承而来的。object类是Python中最顶层的类,定义了所有类的基本方法。在Python中,object类中有两个特殊方法,分别是__str__()方法和对象比较方法。下面分别介绍这两个方法。



8.7.1 str() 方法


在Python中,所有对象都有一个__str__()方法,它返回一个字符串表示对象。如果我们在定义一个类时没有实现__str__()方法,则默认返回一个包含对象的类名和内存地址的字符串。


下面是一个例子:


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person("Alice", 18)
print(p)

输出结果:

<__main__.Person object at 0x7f8d4c4cb4f0>

我们可以看到,输出的结果并没有包含Person对象的具体信息。


为了让输出更加有意义,我们可以重写__str__()方法,返回一个字符串表示对象的具体信息。


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __str__(self):
        return f"Person(name={self.name}, age={self.age})"
p = Person("Alice", 18)
print(p)

输出结果:

Person(name=Alice, age=18)

我们可以看到,输出结果已经包含了Person对象的具体信息。


__str__()方法是一个特殊的方法,用于返回一个字符串,表示对象的内容。如果在类中定义了__str__()方法,那么在使用print()函数输出该对象时,会自动调用该方法,并将其返回值作为输出结果。


例如,我们定义一个名为Person的类,其中包含name和age两个实例变量,并定义了__str__()方法,如下所示:


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def __str__(self):
        return 'Name: {} Age: {}'.format(self.name, self.age)

在上面的代码中,__str__()方法返回了一个字符串,格式为“Name: 名字 Age: 年龄”,其中的{}会被实际的变量值所替换。现在,我们创建一个Person对象并输出其内容:


person = Person('Tom', 18)
print(person)

输出结果为:

makefile
Copy code
Name: Tom Age: 18

可以看到,__str__()方法被自动调用,并将其返回值作为输出结果。


8.7.2 对象比较方法


在Python中,我们可以使用==运算符比较两个对象是否相等。如果我们要自定义对象的比较方式,则需要重写__eq__()方法。


下面是一个例子:


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __eq__(self, other):
        if isinstance(other, Point):
            return self.x == other.x and self.y == other.y
        return False
p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(3, 4)
print(p1 == p2)
print(p1 == p3)

输出结果:

True
False

我们可以看到,p1和p2的坐标相同,所以它们相等,而p1和p3的坐标不同,所以它们不相等。


8.8 枚举类


枚举类是一种特殊的类,它定义了一些常量,这些常量的值在定义时已经确定,不能再改变。枚举类可以方便地表示一些有限的取值范围,比如星期几、月份等。


8.8.1 定义枚举类


枚举类是指一组具有特定取值的常量集合,使用枚举类可以提高代码的可读性和可维护性。在Python中,可以使用枚举类来定义一组常量。


要使用枚举类,需要先导入enum模块,然后通过继承Enum类来定义枚举类。


from enum import Enum
class Weekday(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

上面的代码定义了一个名为Weekday的枚举类,它包含了一组代表星期几的常量。


在定义枚举类时,每个常量都是类变量,并且其值是唯一的。


8.8.2 限制枚举类


默认情况下,Python的枚举类是可以被重新赋值的,但是在某些情况下,我们希望枚举类的常量不被重新赋值。在这种情况下,可以使用@unique装饰器来限制枚举类的取值。


from enum import Enum, unique
@unique
class Weekday(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

8.8.3 使用枚举类


定义好枚举类之后,就可以通过类名和枚举常量名来访问枚举常量。


from enum import Enum
class Weekday(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7
print(Weekday.MONDAY)  # Weekday.MONDAY
print(Weekday.MONDAY.value)  # 1
print(Weekday['MONDAY'])  # Weekday.MONDAY
print(Weekday(1))  # Weekday.MONDAY

在上面的代码中,我们首先使用Weekday.MONDAY来访问枚举常量,然后使用.value属性来访问枚举常量的值。我们还可以使用Weekday['MONDAY']或Weekday(1)来访问枚举常量。



大家好,欢迎来到 Python 编程教程的第 9 章,本章节将介绍异常处理的相关知识,包括异常问题举例、异常类继承层次、常见异常、捕获异常、异常堆栈跟踪、释放资源、自定义异常类以及显式抛出异常等。


9.1 异常问题举例

在编程过程中,有时会出现一些意外情况导致程序无法正常运行,比如文件不存在、除数为零等等。这时候就需要使用异常处理来处理这些异常情况,使程序不会因为异常情况而崩溃或产生错误的结果。


9.2 异常类继承层次

在 Python 中,所有异常都是从 BaseException 类派生而来的。其中,常见的异常类还包括 Exception、ArithmeticError、LookupError、IOError 等。这些异常类都有各自的特定含义和用途,可以根据具体情况选择使用哪种异常类来处理异常情况。


9.3 常见异常

下面是一些常见的异常类及其含义:


9.3.1 AttributeError 异常

当试图访问一个对象没有的属性时,会引发 AttributeError 异常。


9.3.2 OSError 异常

当操作系统无法执行指定的操作时,会引发 OSError 异常。


9.3.3 IndexError 异常

当使用一个不存在的索引访问序列时,会引发 IndexError 异常。


9.3.4 KeyError 异常

当使用一个不存在的键访问字典时,会引发 KeyError 异常。


9.3.5 NameError 异常

当尝试访问一个不存在的变量或函数时,会引发 NameError 异常。


9.3.6 TypeError 异常

当操作或函数应用于不适当类型的对象时,会引发 TypeError 异常。


9.3.7 ValueError 异常

当操作或函数的参数具有不正确的值时,会引发 ValueError 异常。


9.4 捕获异常

在 Python 中,可以使用 try-except 语句来捕获和处理异常。try 代码块中的代码会被执行,如果其中引发了异常,就会跳转到 except 代码块中执行相应的处理代码。以下是 try-except 语句的基本语法:



try:
    # 执行可能引发异常的代码
except 异常类型1:
    # 处理异常类型1的代码
except 异常类型2:
    # 处理异常类型2的代码
else:
    # 如果没有引发任何异常,则执行else代码块中的代码
finally:
    # 无论是否引发异常,都会执行finally代码块中的代码


9.4.1 try-except 语句


try-except 语句是捕获异常最基本的方法,下面是一个简单的例子,演示了如何使用 try-except 语句来捕获异常:


try:
    num = int(input("请输入一个整数:"))
    result = 10 / num
    print(result)
except ZeroDivisionError:
    print("除数不能为零")
except ValueError:
    print("输入的不是整数")

在上面的代码中,程序首先尝试读入一个整数,如果读入成功,则尝试将 10 除以该整数并打印结果。如果读入的不是整数,或者读入的是零,则会引发相应的异常,程序会跳转到相应的 except 代码块中执行相应的处理代码。如果没有引发任何异常,则程序会继续执行 else 代码块中的代码。


9.4.2 多 except 代码块

在 try-except 语句中,可以使用多个 except 代码块来处理不同类型的异常。例如:


try:
    # 执行可能引发异常的代码
except 异常类型1:
    # 处理异常类型1的代码
except 异常类型2:
    # 处理异常类型2的代码

在上面的代码中,如果 try 代码块中的代码引发了异常类型 1,则会跳转到第一个 except 代码块中执行相应的处理代码;如果引发的是异常类型 2,则会跳转到第二个 except 代码块中执行相应的处理代码。


9.4.3 try-except 语句嵌套

在 try-except 语句中,可以嵌套其他的 try-except 语句,以便更精确地处理异常。例如:


try:
    # 执行可能引发异常的代码
except 异常类型1:
    try:
        # 处理异常类型1的代码
    except 异常类型2:
        # 处理异常类型2的代码

在上面的代码中,如果 try 代码块中的代码引发了异常类型 1,则会跳转到第一个 except 代码块中执行相应的处理代码,如果第一个 except 代码块中的代码引发了异常类型 2,则会跳转到第二个 except 代码块中执行相应的处理代码。


9.4.4 多重异常捕获

在 try-except 语句中,也可以捕获多种异常类型,例如:


try:
    # 执行可能引发异常的代码
except (异常类型1, 异常类型2):
    # 处理异常类型1和异常类型2的代码

在上面的代码中,如果 try 代码块中的代码引发了异常类型 1 或异常类型 2,则会跳转到 except 代码块中执行相应的处理代码。


9.5 异常堆栈跟踪


在 Python 中,如果程序引发了异常而没有被捕获,就会打印出异常堆栈跟踪信息。这个信息包含了程序在执行过程中所有的函数调用栈、文件名和行号等信息,可以帮助程序员快速定位代码中的错误。


下面是一个例子,演示了如何打印异常堆栈跟踪信息:


def func1():
    func2()
def func2():
    func3()
def func3():
    raise ValueError("这是一个测试异常")
try:
    func1()
except Exception as e:
    import traceback
    traceback.print_exc()

在上面的代码中,定义了三个函数 func1、func2 和 func3,其中 func3 引发了一个 ValueError 异常。在 try 代码块中,调用了 func1 函数,由于 func3 引发了异常,程序会打印出异常堆栈跟踪信息。输出结果如下:


Traceback (most recent call last):
  File "test.py", line 9, in <module>
    func1()
  File "test.py", line 2, in func1
    func2()
  File "test.py", line 5, in func2
    func3()
  File "test.py", line 8, in func3
    raise ValueError("这是一个测试异常")
ValueError: 这是一个测试异常

在上面的输出结果中,可以看到每个函数调用的文件名、行号以及函数名,以及最终引发异常的文件名、行号和异常类型和异常信息。


9.6 释放资源

在 Python 中,有些资源是需要手动释放的,例如打开的文件、网络连接、数据库连接等。如果不及时释放这些资源,会造成系统资源的浪费或者出现其他的异常。


为了避免这种情况的发生,Python 提供了多种方式来自动释放资源,包括 finally 代码块、else 代码块和 with 语句。


9.6.1 finally 代码块

finally 代码块是一种无论 try 代码块是否引发异常都会被执行的代码块。这种代码块通常用来释放资源或者执行清理操作,例如关闭文件或者数据库连接。例如:


try:
    f = open("test.txt", "r")
    # 执行文件操作
finally:
    f.close()

在上面的代码中,try 代码块打开了一个文件进行读取操作,无论文件操作是否成功,finally 代码块都会被执行来关闭文件。


9.6.2 else 代码块


else 代码块是一种只有在 try 代码块成功执行完毕之后才会被执行的代码块。如果 try 代码块引发了异常,则 else 代码块不会被执行。例如:


try:
    f = open("test.txt", "r")
    # 执行文件操作
except IOError:
    print("文件不存在")
else:
    print("文件读取成功")

在上面的代码中,如果文件打开成功,则会执行 else 代码块并输出文件读取成功的信息,否则会捕获 IOError 异常并输出文件不存在的信息。


9.6.3 with as 代码块自动资源管理

with as 语句是一种自动资源管理机制,可以确保在代码执行完毕后自动释放资源。例如:

with open("test.txt", "r") as f:

    # 执行文件操作

在上面的代码中,with as 语句打开了一个文件进行读取操作,当代码块执行完毕后,文件会自动关闭并释放资源。


9.7 自定义异常类

除了 Python 内置的异常类之外,程序员也可以自定义自己的异常类。自定义异常类可以继承自 Exception 类或者它的子类。例如:


class MyException(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

在上面的代码中,定义了一个名为 MyException 的异常类,它继承自 Exception 类。在类的构造函数中,定义了一个名为 value 的属性来保存异常信息,在 str 方法中将异常信息转换成字符串形式。这个异常类可以用来抛出一些自定义的异常信息。


9.8 显式抛出异常

除了捕获异常之外,程序员还可以显式地抛出异常。Python 中提供了 raise 语句来抛出异常。例如:


x = -1
if x < 0:
    raise ValueError("x不能是负数")

在上面的代码中,如果 x 的值是负数,则会抛出一个 ValueError 异常,并输出 x 不能是负数 的信息。


总结

异常处理是 Python 程序中非常重要的一部分。Python 提供了多种异常处理机制,包括 try-except 语句、finally 代码块、else 代码块、with 语句等。通过合理使用这些机制,可以使程序在出现异常时能够优雅地处理异常,避免程序崩溃或者出现其他问题。


另外,Python 还提供了许多内置异常类,包括 AttributeError、OSError、IndexError、KeyError、NameError、TypeError、ValueError 等。程序员可以根据自己的需要选择合适的异常类来处理异常。


在编写程序时,应该尽可能地避免出现异常情况。如果出现异常,应该在合适的位置进行捕获和处理,以确保程序的正常运行。同时,在处理异常时,应该考虑到代码的可读性和可维护性,避免出现过于复杂的异常处理代码。


最后,自定义异常类和显式抛出异常是异常处理的两种重要手段。程序员可以根据自己的需要定义自己的异常类,并在必要的时候显式抛出异常,以提高代码的可读性和可维护性。


第10章 常用模块


在编写Python程序时,我们可以使用各种模块来扩展功能。模块是一个包含一组相关功能的Python代码文件。Python标准库包含了很多有用的模块,这些模块可以帮助我们更轻松地编写程序。在这一章中,我们将介绍一些常用的模块,包括math模块、random模块、datetime模块和logging模块。


10.1 math模块


math模块是Python标准库中的一个数学库,提供了一些基本的数学函数。在使用这些函数之前,我们需要通过import语句导入math模块。


import math

10.1.1 舍入函数


舍入函数可以将一个数值四舍五入到最接近的整数、最接近的偶数、指定的小数位数等。下面是一些常用的舍入函数:


# 四舍五入到最接近的整数
print(round(2.5))  # 输出 3
print(round(3.5))  # 输出 4


# 四舍五入到最接近的偶数
print(round(1.5))  # 输出 2
print(round(2.5))  # 输出 2


# 四舍五入到指定的小数位数
print(round(3.1415926, 3))  # 输出 3.142


10.1.2 幂和对数函数


math模块还提供了一些幂和对数函数。下面是一些常用的函数:


# 求幂
print(math.pow(2, 3))  # 输出 8.0


# 求平方根
print(math.sqrt(4))  # 输出 2.0
# 求自然对数
print(math.log(10))  # 输出 2.302585092994046


# 求以2为底的对数
print(math.log2(8))  # 输出 3.0


# 求以10为底的对数
print(math.log10(100))  # 输出 2.0


10.1.3 三角函数


math模块还提供了一些三角函数,如正弦、余弦、正切等。这些函数接收的参数是弧度值,而不是角度值。我们可以使用math.radians()函数将角度转换为弧度。



# 将角度转换为弧度
print(math.radians(180))  # 输出 3.141592653589793


# 求正弦值
print(math.sin(math.pi/6))  # 输出 0.5


# 求余弦值
print(math.cos(math.pi/3))  # 输出 0.5


# 求正切值
print(math.tan(math.pi/4))  # 输出 0.9999999999999999


10.2 random模块


random模块是Python标准库中的随机数生成模块,提供了一些生成随机数的函数。在使用这些函数之前,我们需要通过import语句导入random模块。

import random

random模块中的一些常用函数如下:


# 生成一个[0, 1)之间的随机实数
print(random.random())


# 生成一个指定范围内的随机整数
print(random.randint(1, 10))


# 生成一个指定范围内的随机实数
print(random.uniform(1, 10))


# 从序列中随机选择一个元素
print(random.choice(['apple', 'banana', 'orange']))


# 将序列中的元素随机排序
print(random.shuffle([1, 2, 3, 4, 5]))

10.3 datetime模块


datetime模块提供了处理日期和时间的函数和类。在使用这些函数和类之前,我们需要通过import语句导入datetime模块。

import datetime


10.3.1 datetime、date和time类


datetime模块中定义了datetime、date和time等类,这些类提供了一些方法来处理日期和时间。下面是一些常用的方法:



# 获取当前日期和时间
now = datetime.datetime.now()
print(now)
# 获取当前日期
today = datetime.date.today()
print(today)


# 获取当前时间
now_time = datetime.datetime.now().time()
print(now_time)


# 创建一个指定日期和时间的datetime对象
dt = datetime.datetime(2022, 12, 31, 23, 59, 59)
print(dt)


# 创建一个指定日期的date对象
d = datetime.date(2022, 12, 31)
print(d)


# 创建一个指定时间的time对象
t = datetime.time(23, 59, 59)
print(t)


10.3.2 日期时间计算


datetime模块中的datetime、date和time类提供了一些方法来进行日期和时间的计算。下面是一些常用的方法:


# 计算两个日期之间的天数
d1 = datetime.date(2022, 1, 1)
d2 = datetime.date(2022, 12, 31)
delta = d2 - d1
print(delta.days)


# 计算当前日期的前一天
yesterday = datetime.date.today() - datetime.timedelta(days=1)
print(yesterday)


# 计算当前时间的前一分钟
prev_minute = datetime.datetime.now() - datetime.timedelta(minutes=1)
print(prev_minute)


10.3.3 日期时间格式化和解析


datetime模块中的datetime、date和time类提供了一些方法来进行日期和时间的格式化和解析。下面是一些常用的方法:



# 将datetime对象格式化为字符串
dt = datetime.datetime(2022, 12, 31, 23, 59, 59)
dt_str = dt.strftime('%Y-%m-%d %H:%M:%S')
print(dt_str)


# 将字符串解析为datetime对象
dt_str = '2022-12-31 23:59:59'


dt = datetime.datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
print(dt)
#将date对象格式化为字符串
d = datetime.date(2022, 12, 31)
d_str = d.strftime('%Y-%m-%d')
print(d_str)
#将字符串解析为date对象
d_str = '2022-12-31'
d = datetime.datetime.strptime(d_str, '%Y-%m-%d').date()
print(d)


10.3.4 时区


datetime模块中的timezone类提供了时区相关的功能。下面是一些常用的方法:


# 获取当前时区
tz = datetime.datetime.now().astimezone().tzinfo
print(tz)
# 创建一个指定时区的datetime对象
dt = datetime.datetime(2022, 12, 31, 23, 59, 59, tzinfo=datetime.timezone(datetime.timedelta(hours=8)))
print(dt)

10.4 logging日志模块


logging模块提供了一些功能强大的日志记录功能,可以帮助我们记录应用程序运行时的事件和状态,以及帮助我们快速定位和解决问题。在使用这些函数之前,我们需要通过import语句导入logging模块。


import logging


10.4.1 日志级别


logging模块中定义了多个日志级别,分别为debug、info、warning、error和critical,级别从低到高。下面是一些常用的方法:


# 设置日志级别
logging.basicConfig(level=logging.DEBUG)
# 记录debug级别的日志
logging.debug('debug message')
# 记录info级别的日志
logging.info('info message')
# 记录warning级别的日志
logging.warning('warning message')
# 记录error级别的日志
logging.error('error message')
# 记录critical级别的日志
logging.critical('critical message')


10.4.2 日志信息格式化

日志记录基础

在Python中,我们可以使用内置的logging模块来记录日志信息。logging模块可以记录信息、警告、错误等级别的日志信息,并将它们写入文件或控制台输出。


以下是一个简单的Python程序,演示如何使用logging模块记录日志信息:


import logging
logging.basicConfig(filename='example.log', level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

在这个示例中,我们首先导入了logging模块,并使用basicConfig()方法配置了日志记录器。我们指定了要记录日志信息的文件名和记录的日志信息级别(在这个例子中,我们记录了所有级别的日志信息)。


接下来,我们使用logging.debug(),logging.info(),logging.warning(),logging.error()和logging.critical()方法记录了不同级别的日志信息。这些方法的用法非常简单,只需要传入一个字符串作为日志信息即可。


如果我们运行这个程序,它将会在同一目录下创建一个名为“example.log”的文件,并将日志信息写入该文件中。同学们可以打开这个文件,查看程序记录的日志信息。


日志信息格式化

logging模块允许我们使用类似于Python字符串格式化的方式来格式化日志信息。例如,我们可以使用“%(levelname)s”表示日志级别,使用“%(asctime)s”表示日志记录时间,使用“%(message)s”表示日志信息本身。


以下是一个使用格式化字符串的Python程序示例:


import logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

在这个示例中,我们在basicConfig()方法中指定了一个格式化字符串,该字符串包含了我们想要记录的各种信息。当我们记录日志信息时,logging模块将自动替换格式化字符串中的占位符。


10.4.3 日志重定位 


在一些情况下,我们希望将日志信息同时输出到控制台和日志文件中。logging模块提供了一种简单的方法,可以将日志信息同时输出到多个位置。


以下是一个将日志信息同时输出到控制台和文件的Python程序示例:


import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# 将日志信息输出到文件中
file_handler = logging.FileHandler('example.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
# 将日志信息输出到控制台中
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)
#将两个处理器添加到记录器中
logger.addHandler(file_handler)
logger.addHandler(console_handler)
#记录日志信息
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')

在这个示例中,我们首先创建了一个名为“logger”的记录器,并设置了记录级别为DEBUG。我们还定义了一个格式化器,将日志信息格式化为“%(asctime)s - %(levelname)s - %(message)s”的形式。


接下来,我们创建了两个处理器:一个将日志信息输出到文件中,另一个将日志信息输出到控制台中。我们还设置了处理器的级别和格式化器。


最后,我们将两个处理器添加到记录器中,并使用logger.debug(),logger.info(),logger.warning(),logger.error()和logger.critical()方法记录了不同级别的日志信息。这些日志信息将同时输出到文件和控制台。


10.4.4 使用配置文件


在实际应用中,我们可能需要在多个Python程序中使用相同的日志记录配置。为了避免重复编写配置代码,我们可以使用配置文件来配置日志记录器。


以下是一个使用配置文件的Python程序示例:


import logging.config
logging.config.fileConfig('logging.conf')
# 创建一个记录器
logger = logging.getLogger('exampleLogger')
# 记录日志信息
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')

在这个示例中,我们首先导入了logging.config模块,并使用fileConfig()方法加载了一个名为“logging.conf”的配置文件。这个配置文件包含了日志记录器的各种配置信息。


接下来,我们使用getLogger()方法创建了一个名为“exampleLogger”的记录器,并使用logger.debug(),logger.info(),logger.warning(),logger.error()和logger.critical()方法记录了不同级别的日志信息。


在这个示例中,我们只提供了Python程序的代码部分。实际上,“logging.conf”配置文件应该包含各种日志记录器的配置信息,例如处理器、格式化器和过滤器等。同学们可以在网上找到许多示例配置文件,以供参考和使用。


这就是Python中日志记录的基础知识。使用logging模块记录日志信息可以帮助我们快速定位问题并解决它们。希望这个教程对你有帮助!



欢迎来到Python编程教程!在这个教程中,我们将学习如何使用正则表达式,这是一种强大的文本处理工具。在这个教程中,我们将按照以下目录逐步介绍正则表达式的各个方面。


第11章 正则表达式

11.1 正则表达式字符串

11.1.1 元字符

在正则表达式中,一些字符有特殊的含义,称为元字符。例如,"."表示任何字符,"*"表示0个或多个前一个字符,"+"表示1个或多个前一个字符等等。在这一节中,我们将详细介绍一些常用的元字符,并提供示例说明其用法。


11.1.2 字符转义

在正则表达式中,某些字符具有特殊含义。如果要匹配这些字符本身而不是它们的特殊含义,可以使用反斜杠来转义这些字符。例如,如果要匹配字符"?",可以使用"?"。


11.1.3 开始与结束字符

在正则表达式中,有两个特殊的元字符"^"和"$",它们分别表示匹配字符串的开头和结尾。例如,"^hello"匹配以"hello"开头的字符串,"world$"匹配以"world"结尾的字符串。


11.2 字符类

11.2.1 定义字符类

字符类用方括号表示,包含一个或多个字符,表示匹配这些字符中的任何一个。例如,"[abc]"表示匹配字符"a"、"b"或"c"。


11.2.2 字符类取反

在字符类的开头使用"^"表示取反。例如,"[^abc]"表示匹配不是字符"a"、"b"或"c"的任何字符。


11.2.3 区间

字符类中可以使用连字符"-"表示范围。例如,"[0-9]"表示匹配任何数字字符。


11.2.4 预定义字符类

正则表达式还提供了一些预定义的字符类,可以方便地匹配常见的字符类型,例如"\\d"表示匹配数字字符,"\\w"表示匹配字母、数字和下划线,"\\s"表示匹配空格字符等等。


11.3 量词

11.3.1 量词的使用

量词用来指定前一个字符可以出现的次数。例如,"*"表示0个或多个前一个字符,"+"表示1个或多个前一个字符,"?"表示0个或1个前一个字符,"{n}"表示恰好出现n次,"{n,}"表示至少出现n次,"{n,m}"表示出现n到m次。


11.3.2 贪婪量词和懒惰量词


贪婪量词表示尽可能多地匹配字符,直到不能再匹配为止。例如,"a.*b"匹配以"a"开头,以"b"结尾,中间包含任何字符的字符串。如果有多个可能的匹配,贪婪量词会选择最长的匹配。


懒惰量词表示尽可能少地匹配字符,直到能够匹配为止。例如,"a.*?b"也匹配以"a"开头,以"b"结尾,中间包含任何字符的字符串,但它会选择最短的匹配。


11.4 分组

11.4.1 分组的使用

在正则表达式中,可以使用小括号来创建分组。例如,"(ab)+"表示一个或多个连续的"ab"字符串。


11.4.2 分组命名

分组可以命名,方便后续的引用。例如,"(?P<name>ab)+"表示一个或多个连续的"ab"字符串,并将它们的匹配结果命名为"name"。


11.4.3 反向引用分组

可以使用"\\1"、"\\2"等来引用前面的分组。例如,"(ab)cd\\1"表示以"ab"开头,以"cd"结尾,并且中间包含相同的"ab"字符串的字符串。


11.4.4 非捕获分组

在小括号内使用"?:"来创建非捕获分组。例如,"(?:ab)+"表示一个或多个连续的"ab"字符串,但不会将它们的匹配结果存储起来。


11.5 re模块

11.5.1 search()和match()函数

re模块提供了一些函数来执行正则表达式匹配操作。其中,search()函数用来在字符串中搜索匹配正则表达式的第一个位置,match()函数则用来尝试从字符串开头匹配正则表达式。


11.5.2 findall()和finditer()函数

re模块还提供了findall()和finditer()函数,用于查找字符串中所有匹配正则表达式的子字符串。findall()函数返回一个包含所有匹配结果的列表,finditer()函数返回一个迭代器,可以逐个访问每个匹配结果。


11.5.3 字符串分割

re模块的split()函数可以按照正则表达式将字符串分割成多个子字符串,并返回一个列表。


11.5.4 字符串替换

re模块的sub()函数可以按照正则表达式替换字符串中的部分内容,并返回替换后的字符串。


11.6 编译正则表达式

11.6.1 已编译正则表达式对象

可以使用re模块的compile()函数将正则表达式编译成一个正则表达式对象,可以在多个字符串上执行匹配操作。


11.6.2 编译标志

在编译正则表达式时,可以通过指定编译标志来改变正则表达式的行为。例如,re.IGNORECASE可以忽略大小写,re.DOTALL可以让点号匹配任意字符(包括换行符)。


代码示例

下面是一个简单的正则表达式示例,用于匹配由数字和字母组成的字符串:


import re
# 定义正则表达式
pattern = re.compile(r'\\w+')
# 测试字符串
text = 'Hello, world! 123'
# 匹配字符串
matches = pattern.findall(text)
# 输出匹配结果
print(matches)

输出:

['Hello', 'world', '123']

上述代码中,re.compile()函数将正则表达式编译成一个正则表达式对象。然后使用该对象的findall()方法在字符串中搜索匹配的子字符串,并将结果存储在列表中。


总结

正则表达式是一种强大的文本处理工具,可以用来匹配、搜索、分割和替换字符串。在Python中,可以使用re模块来执行正则表达式操作。掌握正则表达式的基本语法和常用函数,可以帮助孩子更好地处理字符串数据。


下面我将根据目录中的各个知识点再举例说明一下:


11.1 正则表达式字符串

正则表达式是由一些特殊字符和普通字符组成的字符串,它可以用来匹配、搜索、分割和替换字符串。下面是一些常用的元字符:


11.1.1 元字符

元字符是正则表达式中的特殊字符,它们具有特殊的含义。例如,点号(.)可以匹配任意单个字符,星号(*)表示重复零次或多次,问号(?)表示重复零次或一次。


import re
text = 'cat bat hat rat'
# 匹配cat, bat, hat或rat
pattern = re.compile(r'.at')
matches = pattern.findall(text)
print(matches)  # ['cat', 'bat', 'hat', 'rat']

11.1.2 字符转义

在正则表达式中,某些字符具有特殊的含义,如果要匹配这些字符本身,需要使用转义字符(反斜杠)进行转义。例如,要匹配一个点号,需要使用.


import re
text = 'cat.bat.hat.rat'
# 匹配.号
pattern = re.compile(r'\\.')
matches = pattern.findall(text)
print(matches)  # ['.', '.', '.']

11.1.3 开始与结束字符

在正则表达式中,^表示字符串的开头,$表示字符串的结尾。例如,'^hello'可以匹配以hello开头的字符串,'world$'可以匹配以world结尾的字符串。


import re
text = 'hello, world!'
# 匹配以hello开头的字符串
pattern = re.compile(r'^hello')
matches = pattern.findall(text)
print(matches)  # ['hello']
# 匹配以world结尾的字符串
pattern = re.compile(r'world$')
matches = pattern.findall(text)
print(matches)  # ['world']

11.2 字符类

字符类用于匹配一组字符中的任意一个字符。下面是一些常用的字符类:


11.2.1 定义字符类

字符类用方括号[]表示,其中列出了要匹配的字符。例如,[abc]可以匹配a、b或c中的任意一个字符。


import re
text = 'apple banana cherry'
# 匹配以a、b或c开头的单词
pattern = re.compile(r'[abc]\\w+')
matches = pattern.findall(text)
print(matches)  # ['apple', 'banana']


11.2.2 字符类取反

字符类取反使用^字符,表示匹配除了字符类中列出的字符以外的任意一个字符。例如,[^abc]可以匹配除了a、b和c以外的任意一个字符。


import re
text = 'apple banana cherry'
# 匹配不以a、b或c开头的单词
pattern = re.compile(r'[^abc]\\w+')
matches = pattern.findall(text)
print(matches)  # ['cherry']

11.2.3 区间

字符类还可以使用区间表示一组连续的字符。例如,[0-9]可以匹配任意一个数字,[a-z]可以匹配任意一个小写字母。


import re
text = '123-456-7890'
# 匹配电话号码
pattern = re.compile(r'[0-9]{3}-[0-9]{3}-[0-9]{4}')
matches = pattern.findall(text)
print(matches)  # ['123-456-7890']

11.2.4 预定义字符类

正则表达式中还有一些预定义的字符类,它们表示一组常用的字符。例如,\\d表示任意一个数字,\\s表示任意一个空白字符,\\w表示任意一个字母数字字符(包括下划线_)。注意,在Python中需要使用原始字符串(即在字符串前加r)来表示反斜杠,否则会与Python中的转义字符冲突。


import re
text = '123-456-7890'
# 匹配电话号码
pattern = re.compile(r'\\d{3}-\\d{3}-\\d{4}')
matches = pattern.findall(text)
print(matches)  # ['123-456-7890']


11.3 量词

量词用于指定匹配的次数。下面是一些常用的量词:


11.3.1 量词的使用

量词使用在匹配字符、字符类、分组或其他正则表达式构造中,用于指定匹配的次数。例如,a{3}表示匹配三个连续的a,a{3,5}表示匹配三到五个连续的a。


import re
text = 'aaa abc aaabc'
# 匹配三个连续的a
pattern = re.compile(r'a{3}')
matches = pattern.findall(text)
print(matches)  # ['aaa']
# 匹配三到五个连续的a
pattern = re.compile(r'a{3,5}')
matches = pattern.findall(text)
print(matches)  # ['aaa', 'aa']


11.3.2 贪婪量词和懒惰量词

贪婪量词表示尽可能多地匹配字符,懒惰量词表示尽可能少地匹配字符。例如,a+表示匹配一个或多个连续的a,a+?表示尽可能少地匹配一个或多个连续的a。


import re
text = 'aaaaaa'
# 匹配尽可能多的a
pattern = re.compile(r'a+')
matches = pattern.findall(text)
print(matches)  # ['aaaaaa']
# 匹配尽可能少的a
pattern = re.compile(r'a+?')
matches = pattern.findall(text)
print(matches) # ['a', 'a', 'a', 'a', 'a', 'a']


11.4 分组


分组用于将多个字符或字符类看作一个整体,可以使用括号来表示分组。分组可以与量词、或操作符、反向引用等正则表达式构造一起使用。


11.4.1 分组的使用


例如,(ab)+表示匹配一个或多个连续的ab,(a|b)+表示匹配一个或多个连续的a或b。


import re
text = 'abab abbb'
# 匹配一个或多个连续的ab
pattern = re.compile(r'(ab)+')
matches = pattern.findall(text)
print(matches)  # ['ab', 'ab']
# 匹配一个或多个连续的a或b
pattern = re.compile(r'(a|b)+')
matches = pattern.findall(text)
print(matches)  # ['ab', 'ab', 'abb', 'b']

11.4.2 分组命名

分组可以使用命名,以便更好地描述正则表达式的含义。例如,(?P<name>...)表示命名分组,其中name是分组的名称。


import re
text = 'John Smith: 123-456-7890'
# 匹配姓名和电话号码
pattern = re.compile(r'(?P<name>\\w+ \\w+): (?P<phone>\\d{3}-\\d{3}-\\d{4})')
matches = pattern.findall(text)
print(matches)  # [('John Smith', '123-456-7890')]

11.4.3 反向引用分组

反向引用分组用于匹配与前面某个分组匹配的字符串。例如,(ab)\\1表示匹配两个连续的ab。


import re
text = 'abab'
# 匹配两个连续的ab
pattern = re.compile(r'(ab)\\1')
matches = pattern.findall(text)
print(matches)  # ['ab']

11.4.4 非捕获分组

非捕获分组用于将分组匹配但不捕获,不会被包含在匹配结果中。例如,(?:...)表示非捕获分组。


import re
text = 'abab abbb'
# 匹配一个或多个连续的ab,但只返回第一个ab
pattern = re.compile(r'(ab)+')
matches = pattern.findall(text)
print(matches)  # ['ab', 'ab']
# 匹配一个或多个连续的ab,但只返回第一个ab
pattern = re.compile(r'(?:ab)+')
matches = pattern.findall(text)
print(matches)  # ['ab', 'ab']


11.5 re模块

re模块是Python中用于正则表达式操作的模块,提供了一些常用的函数和方法,包括search()、match()、findall()、finditer()、split()、sub()等。


11.5.1 search()和match()函数


search()和match()是两个常用的函数,它们用于在字符串中查找匹配正则表达式的子串。


search(pattern, string, flags=0)函数:在字符串中查找正则表达式的第一个匹配项,并返回一个匹配对象。如果没有找到匹配项,则返回None。下面是一个使用search()函数的例子:


import re
pattern = r'cat'
string = 'A cat and a dog'
result = re.search(pattern, string)
if result:
    print('匹配成功')
else:
    print('匹配失败')
match(pattern, string, flags=0)函数:只匹配字符串的开始部分。如果正则表达式在开始部分没有找到匹配项,则返回None。下面是一个使用match()函数的例子:
python
Copy code
import re
pattern = r'cat'
string = 'A cat and a dog'
result = re.match(pattern, string)
if result:
    print('匹配成功')
else:
    print('匹配失败')


11.5.2 findall()和 finditer()函数


findall()和finditer()函数用于在字符串中查找所有匹配正则表达式的子串。


findall(pattern, string, flags=0)

函数:在字符串中查找所有匹配正则表达式的子串,并返回一个列表。下面是一个使用findall()函数的例子:


import re
pattern = r'cat'
string = 'A cat and a dog'
result = re.findall(pattern, string)
print(result)
finditer(pattern, string, flags=0)

函数:在字符串中查找所有匹配正则表达式的子串,并返回一个迭代器。下面是一个使用finditer()函数的例子:




import re
pattern = r'cat'
string = 'A cat and a dog'
result = re.finditer(pattern, string)
for match in result:
    print(match)


11.5.3 字符串分割

re.split(pattern, string, maxsplit=0, flags=0)函数用于根据正则表达式匹配到的子串分割字符串。


下面是一个使用re.split()函数的例子:


import re
pattern = r'[.?!]'
string = 'Hello. How are you? I am fine.'
result = re.split(pattern, string)
print(result)

输出结果为:

['Hello', ' ', 'How are you', ' ', 'I am fine', '']


11.5.4 字符串替换


re.sub(pattern, repl, string, count=0, flags=0)函数用于根据正则表达式匹配到的子串替换字符串中的内容。

下面是一个使用re.sub()函数的例子:


import re
pattern = r'cat'
string = 'A cat and a dog'
result = re.sub(pattern, 'bird', string)
print(result)

输出结果为:


A bird and a dog


11.6 编译正则表达式


Python中的re模块提供了compile()函数,用于将正则表达式编译成一个正则表达式对象,这样可以提高正则表达式的效率,并且可以重复使用该正则表达式对象。


11.6.1 已编译正则表达式对象


编译完成后,可以使用findall()、search()、match()、split()、sub()等函数,对已编译的正则表达式对象进行操作。


例如,我们可以编译一个正则表达式对象,然后对字符串进行匹配:


import re
pattern = re.compile(r"\\d+")
text = "There are 10 apples and 20 bananas"
result = pattern.findall(text)
print(result)

输出结果为:

['10', '20']


11.6.2 编译标志


compile()函数还可以接受一些标志参数,用于指定正则表达式的匹配方式,例如是否区分大小写,是否多行匹配等。


例如,我们可以编译一个不区分大小写的正则表达式对象:


import re
pattern = re.compile(r"apple", re.I)
text = "There are Apple and apple"
result = pattern.findall(text)
print(result)

输出结果为:

['Apple', 'apple']


好的,接下来是一个综合实例,通过正则表达式进行一个简单的数据清洗。


假设有一个包含学生信息的字符串,每个学生的信息以逗号分隔,其中第一个字段为学生姓名,第二个字段为学生年龄,第三个字段为学生成绩,样例如下:


"张三,20,80;李四,22,75;王五,18,90"

现在我们需要对该字符串进行清洗,将学生信息转换为字典格式,并且只保留成绩大于等于80分的学生信息。


实现思路如下:


使用split()函数将字符串分割成每个学生的信息。

遍历每个学生的信息,使用正则表达式提取出姓名、年龄、成绩。

将学生信息存储到字典中。

对成绩大于等于80分的学生信息进行筛选。

完整代码如下:


import re
text = "张三,20,80;李四,22,75;王五,18,90"
pattern = re.compile(r"([\\u4e00-\\u9fa5]+),(\\d+),(\\d+)")
students = []
# 遍历每个学生信息
for item in text.split(";"):
    # 提取姓名、年龄、成绩
    match = pattern.match(item)
    if match:
        name = match.group(1)
        age = int(match.group(2))
        score = int(match.group(3))
        # 存储学生信息到字典中
        student = {"name": name, "age": age, "score": score}
        students.append(student)
# 筛选成绩大于等于80分的学生信息
students = [item for item in students if item["score"] >= 80]
print(students)

输出结果为:

[{'name': '张三', 'age': 20, 'score': 80}, {'name': '王五', 'age': 18, 'score': 90}]

这个例子展示了正则表达式在数据清洗中的应用,正则表达式可以帮助我们快速地从一堆数据中提取出需要的信息,提高数据处理的效率。


欢迎大家学习Python编程!本次教程将教授如何使用Python进行文件操作与管理。


第 12 章 文件操作与管理


12.1 文件操作


在Python中,文件操作是非常重要的一部分。在我们的程序中,我们经常需要读取文件或者将数据写入文件中。下面是一些基本的文件操作:


12.1.1 打开文件


在Python中,可以使用open()函数来打开文件,可以指定文件名和操作模式。例如,要打开一个名为example.txt的文件,可以使用以下代码:

f = open("example.txt", "r")

这里,我们使用“r”模式打开文件,这表示我们将以只读模式读取文件。


12.1.2 关闭文件


当我们完成文件操作时,应该关闭文件。可以使用close()函数来关闭文件,例如:

f.close()


12.1.3 文本文件读写


文本文件是一个包含文本数据的文件,可以使用Python来读取和写入文本文件。以下是一个例子:


# 打开文件
f = open("example.txt", "w")
# 写入文本
f.write("Hello, world!")
# 关闭文件
f.close()

在这个例子中,我们以“w”模式打开文件,这表示我们将以写模式打开文件。然后我们使用write()函数向文件中写入文本。


如果我们想要读取一个文本文件,我们可以使用以下代码:


# 打开文件
f = open("example.txt", "r")
# 读取文本
text = f.read()
# 关闭文件
f.close()
print(text)

在这个例子中,我们以“r”模式打开文件,并使用read()函数读取文件中的文本。


12.1.4 二进制文件读写


除了文本文件之外,Python还可以读取和写入二进制文件。以下是一个例子:


# 打开文件
f = open("example.bin", "wb")
# 写入二进制数据
f.write(b"\\x01\\x02\\x03")
# 关闭文件
f.close()

在这个例子中,我们以“wb”模式打开文件,这表示我们将以二进制写模式打开文件。我们使用write()函数写入二进制数据。


如果我们想要读取一个二进制文件,我们可以使用以下代码:


# 打开文件
f = open("example.bin", "rb")
# 读取二进制数据
data = f.read()
# 关闭文件
f.close()
print(data)

在这个例子中,我们以“rb”模式打开文件,并使用read()函数读取文件中的二进制数据。


12.2 os 模块


Python中的os模块提供了一些功能来管理操作系统。以下是一些常用的os模块函数:


# 获取当前工作目录
import os
cwd = os.getcwd()
print(cwd)
# 列出目录下的文件
files = os.listdir(cwd)
for file in files:
print(file)
#创建目录
os.mkdir("new_directory")
#移动文件或目录
os.rename("example.txt", "new_directory/example.txt")
#删除文件或目录
os.remove("new_directory/example.txt")
os.rmdir("new_directory")


在这个例子中,我们首先使用os.getcwd()函数获取当前工作目录。然后,我们使用os.listdir()函数列出当前目录中的所有文件。接下来,我们使用os.mkdir()函数创建一个新目录,然后使用os.rename()函数将文件移动到新目录中。最后,我们使用os.remove()和os.rmdir()函数删除文件和目录。


12.3 os.path 模块


os.path模块提供了一些函数来处理路径和文件名。以下是一些常用的os.path模块函数:


#获取文件名
import os.path
filename = os.path.basename("/path/to/file.txt")
print(filename)
#获取目录名
dirname = os.path.dirname("/path/to/file.txt")
print(dirname)
#检查文件是否存在
exists = os.path.exists("/path/to/file.txt")
print(exists)
#检查是否是文件
is_file = os.path.isfile("/path/to/file.txt")
print(is_file)
#检查是否是目录
is_dir = os.path.isdir("/path/to/directory")
print(is_dir)
#拼接路径
path = os.path.join("/path/to", "file.txt")
print(path)

在这个例子中,我们使用os.path.basename()函数获取文件名,使用os.path.dirname()函数获取目录名。我们还可以使用os.path.exists()函数检查文件是否存在,使用os.path.isfile()函数检查文件是否是文件,使用os.path.isdir()函数检查文件是否是目录。最后,我们使用os.path.join()函数将路径组合起来。


感谢同学们阅读本教程,希望同学们已经掌握了Python中的文件操作与管理。祝同学们编程愉快!



野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击