【全篇】Python从零基础到入门

文章目录

第一章 基础语法

1.字面量

字面量:在代码中,被写下来的的固定的值,称之为字面量

类型 描述 说明
数字(Number) 支持整数(int)浮点数(float)复数(complex)布尔(bool) 整数(int),如:10、-10
浮点数(float),如:13.14、-13.14
复数(complex),如:4+3j,以j结尾表示复数
布尔(bool)表达现实生活中的逻辑,即真和假,True表示真,False表示假。True本质上是一个数字记作1,False记作0
字符串(String) 描述文本的一种数据类型 字符串(string)由任意数量的字符组成
列表(List) 有序的可变序列 Python中使用最频繁的数据类型,可有序记录一堆数据
元组(Tuple) 有序的不可变序列 可有序记录一堆不可变的Python数据集合
集合(Set) 无序不重复集合 可无序记录一堆不重复的Python数据集合
字典(Dictionary) 无序Key-Value集合 可无序记录一堆Key-Value型的Python数据集合

字符串(string),又称文本,是由任意数量的字符如中文、英文、各类符号、数字等组成。所以叫做字符的串

  • print(10),输出整数10
  • print(13.14),输出浮点数13.14
  • print("我爱编程"),输出字符串:我爱编程

2.注释

注释:在程序代码中对程序代码进行解释说明的文字。

作用:注释不是程序,不能被执行,只是对程序代码进行解释说明,让别人可以看懂程序代码的作用,能够大大增强程序的可读性。

  • 单行注释:以 #开头,#右边 的所有文字当作说明,而不是真正要执行的程序,起辅助说明作用

    python 复制代码
    #我是单行注释
    print("Hello World")
    
    运行结果:
    Hello World
  • 多行注释: 以 一对三个双引号 引起来 ( """ 注释内容 """ )来解释说明一段代码的作用使用方法

    python 复制代码
    """
    我是多行注释
    我可以写多行
    """
    print("hello,world")
    
    运行结果:
    hello,world

3.变量

变量:在程序运行时,能储存计算结果或能表示值的抽象概念。

简单的说,变量就是在程序运行时,记录数据用的

  • 变量,从名字中可以看出,表示"量"是可变的。所以,变量的特征就是,变量存储的数据,是可以发生改变的。
  • 变量的目的是存储运行过程的数据。存储的目的是为了:重复使用
python 复制代码
#将数字10存到data变量里
data = 10

4.数据类型

数据是有类型的。目前在入门阶段,我们主要接触如下三类数据类型:

类型 描述 说明
string 字符串类型 用引号引起来的数据都是字符串
int 整型(有符号) 数字类型,存放整数 如 -1,10, 0 等
float 浮点型(有符号) 数字类型,存放小数 如 -3.14, 6.66

那么,问题来了,如何验证数据的类型呢?

我们可以通过type()语句来得到数据的类型:
语法:type(被查看类型的数据)

示例代码:

python 复制代码
#1.用print语句,直接输出类型信息
print(type("这是字符串"))
print(type(666))
print(type(3.14))

#运行结果
<class 'str'>
<class 'int'>
<class 'float'>

5.数据类型转换

数据类型之间,在特定的场景下,是可以相互转换的,如字符串转数字、数字转字符串等

跟C语言里面的强制转换很像

数据类型转换,将会是我们以后经常使用的功能。

如:

  • 从文件中读取的数字,默认是字符串,我们需要转换成数字类型
  • 后续学习的input()语句,默认结果是字符串,若需要数字也需要转换
  • 将数字转换成字符串用以写出到外部系统等等

常见的转换语句

语句(函数) 说明
int(x) 将x转换为一个整数
float(x) 将x转换为一个浮点数
str(x) 将对象 x 转换为字符串

同前面学习的type()语句一样,这三个语句,都是带有结果的(返回值)

我们可以用print直接输出

或用变量存储结果值

  1. 任何类型,都可以通过str(),转换成字符串

  2. 字符串内必须真的是数字,才可以将字符串转换为数字

  3. 浮点数转整数会丢失精度,也就是小数部分

6.标识符

在Python程序中,我们可以给很多东西起名字,比如:

  • 变量的名字
  • 方法的名字
  • 类的名字,等等
    这些名字,我们把它统一的称之为标识符,用来做内容的标识。
    所以,标识符:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。

标识符命名规则中,只允许出现:

  1. 英文
  2. 中文(不推荐使用中文)
  3. 数字(数字不可以开头)
  4. 下划线(_)
  • 区分大小写

  • 不可使用关键字

    变量的命名规范

    • 见名知意
    • 下划线命名法
    • 英文字母全小写

7.运算符

a = 10,b = 20

运算符 描述 实例
+ 两个对象相加 a + b 输出结果 30
- 得到负数或是一个数减去另一个数 a - b 输出结果 -10
* 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/ b / a 输出结果 2
// 取整除 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0
% 取余 返回除法的余数 b % a 输出结果 0
** 指数 a**b 为10的20次方, 输出结果 100000000000000000000

赋值运算符

运算符 描述 实例
= 赋值运算符 把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3,结果num的值为7

复合赋值运算符

运算符 描述 实例
+= 加法赋值运算符 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

8.字符串拓展

1.字符串的三种定义方式

  • 单引号方式 name = '张三'
  • 双引号方式 name = "张三"
  • 三引号方式 name = "' 张三 "'

字符串的引号嵌套

  1. 单引号定义法,可以内含双引号
  2. 双引号定义法,可以内含单引号
  3. 可以使用转移字符(\)来将引号解除效用,变成普通字符串

print(" I\ 'm ")

2.字符串拼接(不用)

  1. 变量过多,拼接起来实在是太麻烦了
  2. 字符串无法和数字或其它类型完成拼接。

字符串无法和非字符串变量进行拼接。因为类型不一致,无法接上

3.字符串格式化(了解)

python 复制代码
name = "小明"
message = "大家好,我叫%s"%name
print(message)

#运行结果:
大家好,我叫小明

其中的,%s

  • % 表示:我要占位

  • s 表示:将变量变成字符串放入占位的地方

    所以,综合起来的意思就是:我先占个位置,等一会有个变量过来,我把它变成字符串放到占位的位置

Python中,其实支持非常多的数据类型占位

最常用的是如下三类:

格式符号 转化
%s 将内容转换成字符串,放入占位位置
%d 将内容转换成整数,放入占位位置
%f 将内容转换成浮点型,放入占位位置

多个变量占位,变量要用括号括起来,并按照占位的顺序填入

python 复制代码
str ="字符串abc"
int = 10
float = 3.14
print("这是字符串%s,这是整型数%d,这是浮点数%f"%(str,int,float))

#运行结果:
这是字符串字符串abc,这是整型数10,这是浮点数3.140000

4.格式化的精度控制

我们可以使用辅助符号"m.n"来控制数据的宽度和精度

  • m,控制宽度,要求是数字(很少使用)(设置的宽度小于数字自身,不生效)

  • .n,控制小数点精度(要求是数字,会进行小数的四舍五入)

    示例:

  • %5d:表示将整数的宽度控制在5位,(如数字11,被设置为5d,就会变成:空格 空格 空格 11,用三个空格补足宽度)

  • %5.2f:表示将宽度控制为5,将小数点精度设置为2, 小数点和小数部分也算入宽度计算。

    (如,对11.345设置了%7.2f 后,结果是: 空格 空格 11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35%.2f:表示不限制宽度,只设置小数点精度为2,如11.345设置%.2f后,结果是11.35)

  • %.2f:表示不限制宽度,只设置小数点精度为2,(如11.345设置%.2f后,结果是11.35)

5.字符串格式化2(常用)

语法:f"{变量} {变量}"的方式进行快速格式化

这种写法不做精度控制,也不理会类型。适用于快速格式化字符串(可以说是原样输出了)

6.对表达式格式化

表达式:一条具有明确执行结果的代码语句

如:

1 + 1、5 * 2,就是表达式,因为有具体的结果,结果是一个数字

又或者,常见的变量定义:

name = "张三" age = 11 + 11

等号右侧的都是表达式呢,因为它们有具体的结果,结果赋值给了等号左侧的变量。

在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码哦

至此,已经学会了两种字符串格式化的方法

  • f"{表达式}"

  • "%s%d%f" % (表达式、表达式、表达式)

小练习

python 复制代码
name,公司名
stock_price,当前股价
stock_code,股票代码
stock_price_daily_growth_factor,股票每日增长系数,浮点数类型,比如1.2
growth_days,增长天数

name = "橘猫"
stock_price = 19.99
stock_code = 003032
stock_price_daily_growth_factor = 1.2
growth_days = 7
price = stock_price*stock_price_daily_growth_factor**growth_days
print(f"公司{name},股票代码{stock_code},当前股价{stock_price}")
print("每日增长系数%d,经过%d天的增长后,股价达到了:%d"%(stock_price_daily_growth_factor,growth_days,price))

9.数据输入

关键词:input()函数

  1. input()语句的功能是,获取键盘输入的数据
  2. 可以使用:input(提示信息),用以在使用者输入内容之前显示提示信息。
  3. 要注意,无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型

input不管你输入的什么数据类型,它输出的统一都是字符串,所以如果我们需要别的类型时,需要进行强转

10.python中定义字符串前面加b、u、r的含义

1.1 基本格式

python 复制代码
str = b"xxxx"
str = u"xxxx"
str = r"xxxx"
str = f"xxxx"

1.2 描述及对比

(1)字符串前面加b表示后面字符串是bytes类型,以便服务器或浏览器识别bytes数据类型;

(2)字符串前面加u表示以Unicode格式进行编码,往往用来解决中文乱码问题,一般英文字符串基本都可以正常解析,而中文字符串必须表明用什么编码,否则就会乱码。

(3)字符串前面加r表示以raw string格式进行定义,可以防止字符串规避反斜杠\的转义。
例如:

python 复制代码
str1 = "\thello"
str2 = r"\thello"
print("str1 =",str1)
print("str2 =",str2)

输出

python 复制代码
str1 =  	hello
str2 = \thello

(4)字符串前面加f表示能支持大括号里面的表达式。

例如:

python 复制代码
python = "蟒蛇"
print("我要好好学{python}!")
print(f"我要好好学{python} !")

输出

python 复制代码
我要好好学{python} !
我要好好学蟒蛇 !

(5)在python3中,bytes和str的相互转换

python 复制代码
str.encode('utf-8')

bytes.decode('utf-8')

例如:

python 复制代码
print("你好".encode(encoding="utf-8"))

输出b'\xe4\xbd\xa0\xe5\xa5\xbd'

python 复制代码
print(b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode())

输出你好

往往用于图片、音视频等文件的读写时,可用bytes数据。

第二章 判断语句

1.布尔类型

布尔类型的字面量:

  • True 表示真(是、肯定)
  • False 表示假 (否、否定)

定义变量存储布尔类型数据:变量名称 = 布尔类型字面量

布尔类型不仅可以自行定义,,同时也可以通过计算的来。

也就是使用比较运算符进行比较运算得到布尔类型的结果。

运算符 描述 示例
== 判断内容是否相等,满足为True,不满足为False 如a=3,b=3,则(a == b) 为 True
!= 判断内容是否不相等,满足为True,不满足为False 如a=1,b=3,则(a != b) 为 True
> 判断运算符左侧内容是否大于右侧满足为True,不满足为False 如a=7,b=3,则(a > b) 为 True
< 判断运算符左侧内容是否小于右侧满足为True,不满足为False 如a=3,b=7,则(a < b) 为 True
>= 判断运算符左侧内容是否大于等于右侧满足为True,不满足为False 如a=3,b=3,则(a >= b) 为 True
<= 判断运算符左侧内容是否小于等于右侧满足为True,不满足为False 如a=3,b=3,则(a <= b) 为 True

2.if语句基本格式

if 要判断的条件:

​ 条件成立时,要做的事

python 复制代码
#1.定义变量
age = 30
#2.进行判断 
if age >= 18:
	print("我已经成年了")

判断语句的结果,必须是布尔类型 True 或 False
True会执行if内的代码语句
False则不会执行

3.if else 语句

python 复制代码
if 条件1:
    条件1满足应做的事情
    条件1满足应做的事情
    ......
else:
    不满足条件时要做的事情1
    不满足条件时要做的事情2
  1. else后,不需要判断条件

  2. 和if的代码块一样,else的代码块同样需要4个空格作为缩进

4.if elif else语句

elif 将elseif缩写了

python 复制代码
if 条件1:
    条件1满足应做的事情
    条件1满足应做的事情
    ......
elif 条件2:
    条件2满足应做的事情
    条件2满足应做的事情
    ......
else:

使用if elif else的注意点有:

  • elif可以写多个
  • 判断是互斥且有序的,上一个满足后面的就不会判断了
  • 可以在条件判断中,直接写input语句,节省代码量

5.判断语句的嵌套

字面意思就是一个if语句里面又套了一个if语句

基础语法:

python 复制代码
if 条件1:
    要做什么事
    if 条件2:
    	要做什么事

嵌套的关键点,在于:空格缩进
通过空格缩进,来决定语句之间的:层次关系

如图:

  • 判断有2层
  • 当外层if满足条件(图中编号1)时,才会执行内层if判断(图中编号2)
  • 当外层if(编号1)不满足,直接执行外层esle

第三章 循环语句

1.while循环

1.基本语法

python 复制代码
while 条件:
	执行的事情1
    执行的事情2
    执行的事情3
    
#示例代码    
i = 0
while i<100:
    print("hello,world")
    i+=1
  1. while的条件需得到布尔类型,True表示继续循环,False表示结束循环

  2. 需要设置循环终止的条件,如i += 1配合 i < 100,就能确保100次后停止,否则将无限循环

  3. 空格缩进和if判断一样,都需要设置

2.基础案例

设置一个范围1-100的随机整数变量,通过while循环,配合input语句,判断输入的数字是否等于随机数

  • 无限次机会,直到猜中为止
  • 每一次猜不中,会提示大了或小了
  • 猜完数字后,提示猜了几次

提示:

无限次机会,终止条件不适合用数字累加来判断,可以考虑布尔类型本身(True or False)

需要提示几次猜中,就需要提供数字累加功能

python 复制代码
"""
演示while循环的基础案例 - 猜数字
"""

# 获取范围在1-100的随机数字
import random
num = random.randint(1, 100)
# 定义一个变量,记录总共猜测了多少次
count = 0

# 通过一个布尔类型的变量,做循环是否继续的标记
flag = True
while flag:
    guess_num = int(input("请输入你猜测的数字:"))
    count += 1
    if guess_num == num:
        print("猜中了")
        # 设置为False就是终止循环的条件
        flag = False
    else:
        if guess_num > num:
            print("你猜的大了")
        else:
            print("你猜的小了")

print(f"你总共猜测了{count}次")

3.嵌套应用

python 复制代码
while 条件1:
	执行的事情1
    执行的事情2
    执行的事情3
    while 条件2:
        执行的事情1
        执行的事情2
        执行的事情3

嵌套循环的使用难点:循环条件的控制,层次越多越复杂,需要细心+耐心

python 复制代码
"""
演示while循环的嵌套使用
嵌套循环需要注意的地方:
	1.注意条件的控制,避免无限循环
	2.多层嵌套,主要空格缩进来确定层次关系

"""

# 外层:表白100天的控制
# 内层:每天的表白都送10只玫瑰花的控制

i = 1
while i <= 100:
    print(f"今天是第{i}天,准备表白.....")

    # 内层循环的控制变量
    j = 1
    while j <= 10:
        print(f"送给小美第{j}只玫瑰花")
        j += 1

    print("小美,我喜欢你")
    i += 1

print(f"坚持到第{i - 1}天,表白成功")

补充知识:

end = ' '

  1. 默认print语句输出内容会自动换行
  1. 在print语句中,加上 end='' 即可输出不换行

制表符\t

在字符串中,有一个特殊符号:\t,效果等同于在键盘上按下:tab键。

它可以让我们的多行字符串进行对齐。


4.嵌套案例

python 复制代码
"""
演示使用while的嵌套循环
打印输出九九乘法表
"""

# 定义外层循环的控制变量
i = 1
while i <= 9:

    # 定义内层循环的控制变量
    j = 1
    while j <= i:
        # 内层循环的print语句,不要换行,通过\t制表符进行对齐
        print(f"{j} * {i} = {j * i}\t", end='')
        j += 1

    i += 1
    print()     # print空内容,就是输出一个换行

2.for 循环

1.for循环的基本语法

  • while循环的循环条件是自定义的,自行控制循环条件
  • for循环是一种"轮询"机制,是对一批内容进行"逐个处理"
  • 同while循环不同,for循环是无法定义循环条件的。只能从被处理的数据集中,依次取出内容进行处理。所以,理论上讲,Python的for循环无法构建无限循环(被处理的数据集不可能无限大)
python 复制代码
#从待处理数据集中:逐个取出数据,赋值给临时变量
语法:
for 临时变量 in 待处理数据集: 
        循环满足条件时执行的代码

# 定义字符串name
name = "itheima"

# for循环处理字符串
for x in name: 
       print(x)

练习题

python 复制代码
"""
演示for循环的练习题:数一数有几个a
"""
# 统计如下字符串中,有多少个字母a
name = "itheima is a brand of itcast"

# 定义一个变量,用来统计有多少个a
count = 0

# for 循环统计
# for 临时变量 in 被统计的数据:
for x in name:
    if x == "a":
        count += 1

print(f"被统计的字符串中有{count}个a")

2.range语句

for 临时变量 in 待处理数据集(可迭代对象):

循环满足条件时执行的代码

语法中的:待处理数据集,严格来说,称之为:可迭代类型

可迭代类型指,其内容可以一个个依次取出的一种类型,包括:

  • 字符串
  • 列表
  • 元组等
    目前我们只学习了字符串类型,其余类型在后续章节会详细学习它们

for循环语句,本质上是遍历:可迭代对象。

语法1:

range(num)

获取一个从0开始,到num结束的数字序列(不含num本身)左闭右开

如range(5)取得的数据是:[0, 1, 2, 3, 4]

语法2:

range(num1, num2)

获得一个从num1开始,到num2结束的数字序列(不含num2本身)

如,range(5, 10)取得的数据是:[5, 6, 7, 8, 9]

语法3:

range(num1, num2, step)

获得一个从num1开始,到num2结束的数字序列(不含num2本身)

数字之间的步长,以step为准(step默认为1)

如,range(5, 10, 2)取得的数据是:[5, 7, 9]

python 复制代码
for i in range(5): 
       print(i)
        
输出:
0
1
2
3
4

3.变量作用域

如图代码,思考一下:红框中的print语句,能否访问到变量 i ?

规范上:不允许

实际上:可以

回看for循环的语法,我们会发现,将从数据集(序列)中取出的数据赋值给:临时变量

python 复制代码
for 临时变量 in 待处理数据集(可迭代对象): 
   循环满足条件时执行的代码

临时变量,在编程规范上,作用范围(作用域),只限定在for循环内部

如果在for循环外部访问临时变量:

  • 实际上是可以访问到的
  • 在编程规范上,是不允许、不建议这么做的

如果实在需要在循环外访问循环内的临时变量,可以在循环外预先定义(一般不要这样做,因为i变量的取值如下图所示,并不能改变多少)

如图,每一次循环的时候,都会将取出的值赋予i变量。

  • 由于i变量是在循环之前(外)定义的
  • 在循环外访问i变量是合理的、允许的

4.for循环的嵌套应用

python 复制代码
"""
演示嵌套应用for循环
"""

# 坚持表白100天,每天都送10朵花
# range
i = 0
for i in range(1, 101):
    print(f"今天是向小美表白的第{i}天,加油坚持。")

    # 写内层的循环了
    for j in range(1, 11):
        print(f"给小美送的第{j}朵玫瑰花")

    print("小美我喜欢你")

print(f"第{i}天,表白成功")

5.循环中断:break ,continue

continue

  • 暂时跳过某次循环,直接进行下一次

break

  • 提前退出循环,不再继续
  1. continue和break,在for和while循环中作用一致

  2. 在嵌套循环中,只能作用在所在的循环上,无法对上层循环起作用

python 复制代码
#每天送5朵花,送10天
i = 1
j = 1
while i<=10:
    print(f"今天是送花的第{i}天")
    i+=1
    while j<=5:
        print(f"这是送的第{j}朵花")
        j+=1
        if j==3:
            break #如果是break,到达3之后,后面全部跳过
                  #如果是continue,只会在等于3的时候跳,后面的照样执行

第四章 函数

1.函数介绍

函数:是组织好的,可重复使用的,用来实现特定功能的代码段。

我们使用过的:input()、print()、str()、int()等都是Python的内置函数

提问: 为什么随时都可以使用len()统计长度?

因为,len()是Python内置的函数:

  • 是提前写好的
  • 可以重复使用
  • 实现统计长度这一特定功能的代码段

使用函数的好处是:

  • 将功能封装在函数内,可供随时随地重复利用
  • 提高代码的复用性,减少重复代码,提高开发效率

2.函数定义

python 复制代码
#函数的定义
def 函数名(传入参数):
	函数体
	return 返回值
#函数调用
函数名(传入参数)

① 参数如不需要,可以省略(后续章节讲解)

② 返回值如不需要,可以省略(后续章节讲解)

③ 函数必须先定义后调用

python 复制代码
"""
演示函数基础定义练习案例:自动查核酸
"""

# 定义函数
def check():
    # 编写函数体输出信息
    print("请出示您的健康码以及72小时核酸证明!")

# 调用函数
check()

3.函数参数

传入参数的功能是:在函数进行计算的时候,接受外部(调用时)提供的数据

python 复制代码
"""
演示函数使用参数
"""

# 定义2数相加的函数,通过参数接收被计算的3个数字
def add(x, y, z):
    result = x + y + z
    print(f"{x} + {y} + {z}的计算结果是:{result}")

# 调用函数,传入被计算的3个数字
add(5, 6, 7)

函数定义中 ,提供的x,y和z,称之为:形式参数(形参),表示函数声明将要使用2个参数

  • 参数之间使用逗号进行分隔

函数调用中 ,提供的5,6和7,称之为:实际参数(实参),表示函数执行时真正使用的参数值

  • 传入的时候,按照顺序传入数据,使用逗号分隔

总结

  1. 函数定义中的参数,称之为形式参数
  2. 函数调用中的参数,称之为实际参数
  3. 函数的参数数量不限(也可以没有),使用逗号分隔开
  4. 传入参数的时候,要和形式参数一一对应,逗号隔开

4.函数返回值

所谓"返回值",就是程序中函数完成事情后,最后给调用者的结果

函数体在遇到return后就结束了,所以写在return后的代码不会执行。

语法就是:通过return关键字,就能向调用者返回数据

python 复制代码
def 函数(参数)
	函数体
    return 返回值
变量 = 函数(参数)
python 复制代码
"""
改用上面的代码
"""

# 定义2数相加的函数,通过参数接收被计算的3个数字
def add(x, y, z):
    result = x + y + z
    return result


# 调用函数,传入被计算的3个数字
b = add(5, 6, 7)
print(b)

None类型

思考:如果函数没有使用return语句返回数据,那么函数有返回值吗?

实际上是:有的。

Python中有一个特殊的字面量:None,其类型是:<class 'NoneType'>

无返回值的函数,实际上就是返回了:None这个字面量

None表示:空的、无实际意义的意思

函数返回的None,就表示,这个函数没有返回什么有意义的内容。

也就是返回了空的意思。

python 复制代码
def say_hello():
	print("hello...")
#   return None  None可以主动使用return返回,效果等同于不写return语句:  
#使用变量接收这个函数的返回值
result = say_hello()	
#打印返回值
print(result)		#结果None
#打印返回值类型
print(type(result)) #结果<class 'NoneType'>

None类型应用场景

None作为一个特殊的字面量,用于表示:空、无意义,其有非常多的应用场景。

  • 用在函数无返回值上
  • 用在if判断上
    在if判断中,None等同于False
    一般用于在函数中主动返回None,配合if判断做相关处理
  • 用于声明无内容的变量上
    定义变量,但暂时不需要变量有具体值,可以用None来代替
python 复制代码
#暂不赋予变量具体值
name = None

5.函数说明文档

函数是纯代码语言,想要理解其含义,就需要一行行的去阅读理解代码,效率比较低。

我们可以给函数添加说明文档,辅助理解函数的作用。

其实就是给函数写个注释,说明一下这个函数是干啥的

语法如下:

python 复制代码
def add(x,y):
    """
    函数说明
    :param x: 形参x的说明
    :param y: 形参y的说明
    :return:  返回值的说明
    """
	函数体
    return 返回值

通过多行注释的形式,对函数进行说明解释,内容应写在函数体之前

param 用于解释参数

return 用于解释返回值

在PyCharm编写代码时,可以通过鼠标悬停,查看调用函数的说明文档

6.函数嵌套调用

所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。

如下效果:

如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置

7.变量作用域

变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)
主要分为两类:局部变量和全局变量

1.局部变量

所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效

变量a是定义在testA函数内部的变量,在函数外部访问则立即报错。

局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量

2.全局变量

所谓全局变量,指的是在函数体内、外都能生效的变量

思考:如果有一个数据,在函数A和函数B中都要使用,该怎么办?

答:将这个数据存储在一个全局变量里面

global关键字

使用 global关键字 可以在函数内部声明变量为全局变量, 如下所示:

综合小练习

  • 定义一个全局变量:money,用来记录银行卡余额(默认5000000)

  • 定义一个全局变量:name,用来记录客户姓名(启动程序时输入)

    定义如下的函数:

  • 查询余额函数

  • 存款函数

  • 取款函数

  • 主菜单函数

    要求:

  • 程序启动后要求输入客户姓名

  • 查询余额、存款、取款后都会返回主菜单

  • 存款、取款后,都应显示一下当前余额

  • 客户选择退出或输入错误,程序会退出,否则一直运行

python 复制代码
"""
演示函数综合案例开发
"""

# 定义全局变量money name
money = 5000000
name = None
# 要求客户输入姓名
name = input("请输入您的姓名:")
# 定义查询函数
def query(show_header):
    if show_header:
        print("-------------查询余额------------")
    print(f"{name},您好,您的余额剩余:{money}元")


# 定义存款函数
def saving(num):
    global money    # money在函数内部定义为全局变量
    money += num
    print("-------------存款------------")
    print(f"{name},您好,您存款{num}元成功。")

    # 调用query函数查询余额
    query(False)

# 定义取款函数
def get_money(num):
    global money
    money -= num
    print("-------------取款------------")
    print(f"{name},您好,您取款{num}元成功。")

    # 调用query函数查询余额
    query(False)
# 定义主菜单函数
def main():
    print("-------------主菜单------------")
    print(f"{name},您好,欢迎来到银行ATM。请选择操作:")
    print("查询余额\t[输入1]")
    print("存款\t\t[输入2]")
    print("取款\t\t[输入3]")    # 通过\t制表符对齐输出
    print("退出\t\t[输入4]")
    return input("请输入您的选择:")

# 设置无限循环,确保程序不退出
while True:
    keyboard_input = main()
    if keyboard_input == "1":
        query(True)
        continue    # 通过continue继续下一次循环,一进来就是回到了主菜单
    elif keyboard_input == "2":
        num = int(input("您想要存多少钱?请输入:"))
        saving(num)
        continue
    elif keyboard_input == "3":
        num = int(input("您想要取多少钱?请输入:"))
        get_money(num)
        continue
    else:
        print("程序退出啦")
        break       # 通过break退出循环

第五章函数进阶

1.函数的多返回值

如果一个函数要有多个返回值,该如何书写代码?

python 复制代码
def test_return():
    return 1,2
x,y = test_return()	#按照返回值的顺序,写对应顺序的多个变量接收即可
print(x)		#变量之间用逗号隔开,支持不同类型的数据return
print(y)

2.函数的多种传参方式

使用方式上的不同, 函数有4中常见参数使用方式:

  • 位置参数(根据参数位置来传递参数)
  • 关键字参数(通过"键=值"形式传递参数,可以不限参数顺序 ,可以和位置参数混用,位置参数需在前)
  • 缺省参数(不传递参数值时会使用默认的参数值 默认值的参数必须定义在最后)
  • 不定长参数( 位置不定长传递以*号标记一个形式参数,以元组的形式接受参数,形式参数一般命名为args 关键字不定长传递以**号标记一个形式参数,以字典的形式接受参数,形式参数一般命名为kwargs)

位置参数

位置参数:调用函数时根据函数定义的参数位置来传递参数

python 复制代码
def user_info(name,age,gender)
	print(f'您的名字是{name},年龄是{age},性别是{gender}')
    
user_info('TOM',20,'男')

注意: 传递的参数和定义的参数的顺序及个数必须一致

关键字参数

关键字参数:函数调用时通过"键=值"形式传递参数.作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

python 复制代码
def user_info(name,age,gender):
	print(f'您的名字是{name},年龄是{age},性别是{gender}')
   
#关键字传参
user_info(name ='TOM',age = 20,gender = '男')
#可以不按照固定顺序
user_info(age = 20,name ='TOM',gender = '男')
#可以和位置参数混用,位置参数必须在前,且匹配参数顺序
user_info("小明",age = 20,gender = '男')      #一般不要这样用

注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序

不定长参数

不定长参数:不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景.

作用: 当调用函数时不确定参数个数时, 可以使用不定长参数

不定长参数的类型: ①位置传递 ②关键字传递

python 复制代码
def user_info(*args): #args是固定的拼写,不可以自定义
	print(args)
#('TOM')
user_info('TOM')
#('TOM',18)
user_info('TOM',18)

注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递

缺省参数

缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。

作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.

python 复制代码
def user_info(name,age,gender='男'): #为参数提供默认值,调用函数时可不传该默认参数的值
	print(f'您的名字是{name},年龄是{age},性别是{gender}')

user_info('TOM',20)

user_info('TOM',18,'女')

关键字传递

注意: 参数是"键=值"形式的形式的情况下, 所有的"键=值"都会被kwargs接受, 同时会根据"键=值"组成字典.

python 复制代码
def user_info(**kwargs): #kwargs是固定的拼写,不可以自定义
	print(kwargs)

#('name':TOM','age':18,'id':110)
user_info(name:TOM',age:18,id:110)

3.匿名函数

1.函数作为参数传递

在前面的函数学习中,我们一直使用的函数,都是接受数据作为参数传入:

  • 数字
  • 字符串
  • 字典、列表、元组等

其实,我们学习的函数本身,也可以作为参数传入另一个函数内。

python 复制代码
def test_func(compute):
    result = compute(1,2)
    print(result)
def compute(x,y):
    return x+y
test_func(compute)	#结果:3

函数compute,作为参数,传入了test_func函数中使用。

  • test_func需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定

  • compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了test_func函数使用

  • 最终,在test_func函数内部,由传入的compute函数,完成了对数字的计算操作

所以,这是一种,计算逻辑的传递,而非数据的传递。

就像上述代码那样,不仅仅是相加,相减、相除、等任何逻辑都可以自行定义并作为函数传入。

1.函数本身是可以作为参数,传入另一个函数中进行使用的。2. 将函数传入的作用在于:传入计算逻辑,而非传入数据。

2.lambda匿名函数

函数的定义中

  1. def关键字可以定义带有名称的函数

  2. lambda关键字,可以定义匿名函数(无名称)

  • 有名称的函数,可以基于名称重复使用。
  • 无名称的匿名函数,只可临时使用一次。

匿名函数定义语法:

python 复制代码
lambda 传入参数:函数体(一行代码)
  • lambda 是关键字,表示定义匿名函数
  • 传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
  • 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
  1. 通过def关键字,定义一个函数,并传入,如下图:
python 复制代码
def test_func(computer):
    result = computer(1,2)
    print(result)
def computer(x,y):
    return x+y
test_func(computer)
#结果:3
  1. 也可以通过lambda关键字,传入一个一次性使用的lambda匿名函数
python 复制代码
def test_func(computer):
    result = computer(1,2)
    print(result)
test_func(lambda x,y:x+y)
#结果:3

使用def和使用lambda,定义的函数功能完全一致,只是lambda关键字定义的函数是匿名的,无法二次使用

注意事项:

  • 匿名函数用于临时构建一个函数,只用一次的场景匿名
  • 函数的定义中,函数体只能写一行代码,如果函数体要写多行代码,不可用lambda匿名函数,应使用def定义带名函数

第六章数据容器

1.初识数据容器

学习数据容器,就是为了批量存储或批量使用多份数据

思考一个问题:如果我想要在程序中,记录5名学生的信息,如姓名。

如何做呢?

  1. 定义五个变量(不高级且低效)
python 复制代码
name1 ='王丽红'
name2 ='周杰轮'
name3 ='林俊姐'
name4 ='张学油'
name5 ='刘德滑'
  1. 一个变量完成(优雅、高效,这就是数据容器,一个容器可以容纳多份数据)

    python 复制代码
    #一个变量存多份数据,优雅实在是优雅
    name_list = ['王丽红','周杰轮','林俊姐','张学油','刘德滑']
    print(name_list)

注意用中括号表示,跟C语言的数组很像

Python中的数据容器:

一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素

每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。

数据容器根据特点的不同,如:

  • 是否支持重复元素

  • 是否可以修改

  • 是否有序,等

    分为5类,分别是:

    列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)

2.数据容器:list(列表)

1.列表的定义

基本语法:

python 复制代码
#字面量
[元素1,元素2,元素3....]

#定义变量
变量的名称 = [元素1,元素2,元素3....]

#定义空变量
变量的名称 = []
变量的名称 = list()

列表内的每一个数据,称之为元素

  • 以 [ ] 作为标识
  • 列表内每一个元素之间用, 逗号隔开

元素的数据类型没有任何限制,甚至元素也可以是列表,这样就定义了嵌套列表

2.列表的下标索引

跟C语言的数组很像哦!!! 列表[下标],即可取出

  1. 列表中的每一个元素,都有其位置下标索引,从前向后的方向,从0开始,依次递增
    我们只需要按照下标索引,即可取得对应位置的元素。
  1. 或者,可以反向索引,也就是从后向前:从-1开始,依次递减(-1、-2、-3...)

一般不这样用,正向的就很好

  1. 如果列表是嵌套的列表,同样支持下标索引(二维数组哈哈哈哈)

要注意下标索引的取值范围,超出范围无法取出元素,并且会报错

3.列表的常用操作(增删改查)

列表除了可以:

  • 定义
  • 使用下标索引获取值

以外,列表也提供了一系列功能:

  • 插入元素
  • 删除元素
  • 清空列表
  • 修改元素
  • 统计元素个数
    等等功能,这些功能我们都称之为:列表的方法

3.1列表的查询功能

跟C语言的结构体很像很像,通过 . 来引出方法里面的函数

回忆:函数是一个封装的代码单元,可以提供特定功能。

在Python中,如果将函数定义为class(类)的成员,那么函数会称之为:方法

python 复制代码
#函数
def add(x,y)
	return x+y
#方法
class Student
	def add(self,x,y)
    	return x+y
    
#方法和函数功能一样, 有传入参数,有返回值,只是方法的使用格式不同:
1.函数的使用
num = add(1,2)

2.方法的使用
student = Student()
num =student.add(1,2)

查找某元素的下标

  • 功能:查找指定元素在列表的下标,如果找不到,报错ValueError

  • 语法:列表.index(元素)

    index就是列表对象(变量)内置的方法(函数)

    python 复制代码
    my_list = ["a","b","c"]
    print(my_list.index("b"))	#结果:1

3.2列表的修改功能(方法):

修改特定位置(索引)的元素值:

一句话,直接改就行了

  • 语法:列表[下标] = 值
  • 可以使用如上语法,直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)
python 复制代码
#正向下标
my_list = [1,2,3]
my_list[0] = 5
print(my_list)	#结果:[5,2,3]

#反向下标
my_list = [1,2,3]
my_list[-3] = 5
print(my_list)	#结果:[5,2,3]
插入元素:

insert()

语法:列表.insert(下标, 元素),在指定的下标位置,插入指定的元素

python 复制代码
my_list = [5,6,7]
my_list.insert(2,"A")
print(my_list)	#结果:[5,6,"A",7]

插入的元素代替原先元素的位置,原先的元素向后移

追加元素:

函数一:append()

语法:列表.append(元素),将指定元素,追加到列表的尾部

python 复制代码
my_list = [4,6,5]
my_list.append(4)	 
print(my_list)	#结果:[4,5,4,4]	

my_list = [4,6,5]
my_list.append([5,5,5])	 
print(my_list)	#结果:[4,5,4,[5,5,5]]	

函数二:extend()

语法:列表.extend(其它数据容器),将其它数据容器的内容取出,依次追加到列表尾部

python 复制代码
my_list = [4,6,5]
my_list.extend([5,5,5])	 
print(my_list)	#结果:[4,5,4,5,5,5]	
删除元素
  • 语法1: del 列表[下标]
  • 语法2:列表.pop(下标)
python 复制代码
my_list = [4,6,5]

#方式一
del my_list[1]
print(my_list)	#结果:[4,5]
#方式二
my_list.pop(1)
print(my_list)	#结果:[4,5]

删除某元素在列表中的第一个匹配项

语法:列表.remove(元素)

python 复制代码
my_list = [4,6,5,5,3]
my_list.remove(5)
print(my_list)	#结果:[4,6,5,3]

清空列表内容

语法:列表.clear()

python 复制代码
my_list = [4,6,5,5,3]
my_list.clear()
print(my_list)	#结果:[]

统计某元素在列表内的数量

语法:列表.count(元素)

python 复制代码
my_list = [4,6,5,5,3]
print(my_list.count(5))	#结果:2

统计列表内,有多少元素

语法:len(列表)

可以得到一个int数字,表示列表内的元素数量

python 复制代码
my_list = [4,6,5,"efs",3]
print(len(my_list))	#结果:5

总览

编号 使用方式 作用
1 列表.append(元素) 向列表中追加一个元素
2 列表.extend(容器) 将数据容器的内容依次取出,追加到列表尾部
3 列表.insert(下标, 元素) 在指定下标处,插入指定的元素
4 del 列表[下标] 删除列表指定下标元素
5 列表.pop(下标) 删除列表指定下标元素
6 列表.remove(元素) 从前向后,删除此元素第一个匹配项
7 列表.clear() 清空列表
8 列表.count(元素) 统计此元素在列表中出现的次数
9 列表.index(元素) 查找指定元素在列表的下标找不到报错ValueError
10 len(列表) 统计容器内有多少元素

学习编程,不仅仅是Python语言本身,以后根据方向,会学习更多的框架技术。

除了经常用的,大多数是记忆不下来的。

经过上述对列表的学习,可以总结出列表有如下特点:

  • 可以容纳多个元素(上限为2**63-1、9223372036854775807个)
  • 可以容纳不同类型的元素(混装)
  • 数据是有序存储的(有下标序号)
  • 允许重复数据存在
  • 可以修改(增加或删除元素等)

综合练习

有一个列表,内容是:[21, 25, 21, 23, 22, 20],记录的是一批学生的年龄

请通过列表的功能(方法),对其进行

1.定义这个列表,并用变量接收它

2.追加一个数字31,到列表的尾部

3.追加一个新列表[29, 33, 30],到列表的尾部

4.取出第一个元素(应是:21)

5.取出最后一个元素(应是:30)

6.查找元素31,在列表中的下标位置

python 复制代码
#1.定义这个列表,并用变量接收它
age = [21, 25, 21, 23, 22, 20]
#2.追加一个数字31,到列表的尾部
age.append(31)
#3.追加一个新列表[29, 33, 30],到列表的尾部
age.extend([29,33,30])
#4.取出第一个元素(应是:21)
first = age[0]
#5.取出最后一个元素(应是:30)
first = age[-1]
#6.查找元素31,在列表中的下标位置
print(age.index(31))

4.list(列表)的遍历

while循环

既然数据容器可以存储多个元素,那么,就会有需求从容器内依次取出元素进行操作。

将容器内的元素依次取出进行处理的行为,称之为:遍历、迭代。

py 复制代码
a = 0
while a<len[列表]:
	路人甲 = 列表[a]
    对路人甲进行处理
    a+=1

for循环

python 复制代码
for 临时变量 in 数据容器
	对临时变量进行处理
    
示例代码:
my_list = [1,2,3]
for i in my_list:
	print(i)
    
结果:
1
2
3
whlie for
在循环控制上 while循环可以自定循环条件,并自行控制 for循环不可以自定循环条件,只可以一个个从容器内取出数据
在无限循环上 while循环可以通过条件控制做到无限循环 for循环理论上不可以,因为被遍历的容器容量不是无限的
在使用场景上 while循环适用于任何想要循环的场景 for循环适用于,遍历数据容器的场景或简单的固定次数循环场景

练习案例

定义一个列表,内容是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  • 遍历列表,取出列表内的偶数,并存入一个新的列表对象中
  • 使用while循环和for循环各操作一次
python 复制代码
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = []
a = 0
while a < len(list1):
    if list1[a] % 2 == 0:
        list2.append(list1[a])
    a += 1
print(list2)
结果:
[2, 4, 6, 8, 10]
python 复制代码
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = []
for a in list1:
    if a%2==0:
        list2.append(a)
print(list2)
结果:
[2, 4, 6, 8, 10]

3.数据容器:tuple(元组)

1.元组的定义

思考:列表是可以修改的。如果想要传递的信息,不被篡改,列表就不合适了。

元组同列表一样,都是可以封装多个、不同类型的元素在内。

但最大的不同点在于:元组一旦定义完成,就不可修改

所以,当我们需要在程序内封装数据,又不希望封装的数据被篡改,那么元组就非常合适了

元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。

python 复制代码
#定义元组字面量
(元素,元素,元素.....)
# 定义元组变量
变量名称 = (元素,元素,元素.....)
#定义空元组
变量名称 =()        #方式1
变量名称 =tuple()	#方式2
python 复制代码
#定义3个元素的元组
t1 = (1,"hello",True)
#定义1个元素的元组
t2 = ('hello',)	#注意:必须带有逗号,否则不是元组类型
#元组也支持嵌套
t1 =((1,2,3)(4,5,6))
print(t1[0][0])	#结果:1

2.元组的操作

元组由于不可修改的特性,所以其操作方法非常少

编号 方法 作用
1 index() 查找某个数据,如果数据存在返回对应的下标,否则报错
2 count() 统计某个数据在当前元组出现的次数
3 len(元组) 统计元组内的元素个数
python 复制代码
#根据下标(索引)取出数据
t1 = (1,2,'hello')
print(t1[2])	#结果:'hello'

#根据index(),查找特定元素的第一个匹配项
t1 = (1,2,'hello',3,4,'hello')
print(t1.index('hello'))	#结果:2

#统计某个数据在元组内出现的次数
t1 = (1,2,'hello',3,4,'hello')
print(t1.conunt('hello'))	#结果:2

#统计元组内的元素个数
t1 = (1,2,3)
print(len(t1))				#结果:3

注意

  1. 不可以修改元组的内容,否则会直接报错
  2. 可以修改元组内的list的内容(修改元素、增加、删除、反转等)
python 复制代码
t1 = (1,2,['A','B'])
  1. 不可以替换list为其它list或其它类型

元组的遍历

python 复制代码
#while循环
t1 =(5,6,8)
a = 0
while a<len(t1):
    print(t1[a])
    a+=1
运行结果:
5,6,8
python 复制代码
t1 =(5,6,8)
for a in t1:
    print(a)
运行结果:
5,6,8

3.元组的特点

经过上述对元组的学习,可以总结出列表有如下特点:

  • 可以容纳多个数据

  • 可以容纳不同类型的数据(混装)

  • 数据是有序存储的(下标索引)

  • 允许重复数据存在

  • 不可以修改(增加或删除元素等)

  • 支持for循环

    多数特性和list一致,不同点在于不可修改的特性。

练习案例

定义一个元组,内容是:('周杰轮', 11, ['football', 'music']),记录的是一个学生的信息(姓名、年龄、爱好)

请通过元组的功能(方法),对其进行

  1. 查询其年龄所在的下标位置
  2. 查询学生的姓名
  3. 删除学生爱好中的football
  4. 增加爱好:coding到爱好list内
python 复制代码
t1 = ('周杰轮', 11, ['football', 'music'])

4.数据容器:str(字符串)

字符串是字符的容器,一个字符串可以存放任意数量的字符。

1.字符串的下标(索引)

和其它容器如:列表、元组一样,字符串也可以通过下标进行访问

  • 从前向后,下标从0开始
  • 从后向前,下标从-1开始

同元组一样,字符串是一个:无法修改的数据容器。

如果必须要做,只能得到一个新的字符串,旧的字符串是无法修改

python 复制代码
#通过下标获取特定位置字符
str1 = "hello world"
print(str[0])	#结果:h
print(str[-1])	#结果:d

2.字符串的常用操作

1.查找特定字符串的下标索引值

语法:字符串.index(字符串)

python 复制代码
str1 = "hello world"
print(str1.index("wo"))	#结果:6  注意空格也算一个字符

2.字符串的替换

语法:字符串.replace(字符串1,字符串2)

功能:将字符串内的全部:字符串1,替换为字符串2

注意:不是修改字符串本身,而是得到了一个新字符串哦

python 复制代码
str1 = "hello world"
str2 = str1.replace("wo","you")

print(str1)	#结果 :hello world
print(str2)	#结果: hello yourld

可以看到,字符串name本身并没有发生变化 而是得到了一个新字符串对象

3.字符串的分割

语法:字符串.split(分隔符字符串)

功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中

注意:字符串本身不变,而是得到了一个列表对象

python 复制代码
str1 = "hello everyone hello world"
list1 = str1.split(" ")
print(list1)
print(type(list1))

#结果:
['hello', 'everyone', 'hello', 'world']
<class 'list'>

可以看到,字符串按照给定的 <空格>进行了分割,变成多个子字符串,并存入一个列表对象中。

4.字符串的规整操作

注意字符串不能被修改,只是得到了一个新字符串

  • 去前后空格

语法:字符串.strip()

python 复制代码
str1 = " hello everyone hello world "
list1 = str1.strip()
print(list1)
print(str1)
#结果:
hello everyone hello world
 hello everyone hello world 
  • 去前后指定字符串

语法:字符串.strip(字符串)

python 复制代码
str1 = "112hello everyone hello world212"
list1 = str1.strip("12")
print(list1)
print(str1)
#结果:
hello everyone hello world
112hello everyone hello world212

注意,传入的是"12" 其实就是:"1"和"2"都会移除,是按照单个字符。

5.统计字符串中某字符串的出现次数

语法:字符串.count(字符串)

py 复制代码
str1 = "112hello everyone hello world212"
list1 = str1.count("21")
print(list1)
print(str1)
#结果:
1
112hello everyone hello world212

6.统计字符串的长度

语法:len(字符串)

python 复制代码
str1 = "12 ab !@#$ 你好"
print(len(str1))

可以看出:

  • 数字(1、2、3...)
  • 字母(abcd、ABCD等)
  • 符号(空格、!、@、#、$等)
  • 中文

均算作1个字符

字符串常用操作汇总

编号 操作 说明
1 字符串[下标] 根据下标索引取出特定位置字符
2 字符串.index(字符串) 查找给定字符的第一个匹配项的下标
3 字符串.replace(字符串1, 字符串2) 将字符串内的全部字符串1,替换为字符串2不会修改原字符串,而是得到一个新的
4 字符串.split(字符串) 按照给定字符串,对字符串进行分隔不会修改原字符串,而是得到一个新的列表
5 字符串.strip()字符串.strip(字符串) 移除首尾的空格和换行符或指定字符串
6 字符串.count(字符串) 统计字符串内某字符串的出现次数
7 len(字符串) 统计字符串的字符个数

5.数据容器(序列)的切片

序列是指:内容连续、有序,可使用下标索引的一类数据容器

列表、元组、字符串,均可以可以视为序列。

序列支持切片,即:列表、元组、字符串,均支持进行切片操作

切片:从一个序列中,取出一个子序列

语法:序列[起始下标:结束下标:步长]

表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:

  1. 起始下标表示从何处开始 【可以留空,留空视作从头开始】
  2. 结束下标(不含)表示何处结束 【可以留空,留空视作截取到结尾】
  3. 步长表示,依次取元素的间隔

步长1表示,一个个取元素

步长2表示,每次跳过1个元素取

步长N表示,每次跳过N-1个元素取

步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)

注意,此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)

示例代码:

python 复制代码
my_list = [1, 2, 3, 4, 5]
new_list = my_list[1:4]	# 下标1开始,下标4(不含)结束,步长1
print(new_list)		# 结果:[2, 3, 4]

my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:]	# 从头开始,到最后结束,步长1
print(new_tuple)		# 结果:(1, 2, 3, 4, 5)

my_list = [1, 2, 3, 4, 5]
new_list = my_list[::2]		# 从头开始,到最后结束,步长2
print(new_list)		# 结果:[1, 3, 5]

my_str = "12345"
new_str = my_str[:4:2]	# 从头开始,到下标4(不含)结束,步长2
print(new_str)		# 结果:"13"

my_str = "12345"
new_str = my_str[::-1]	# 从头(最后)开始,到尾结束,步长-1(倒序)
print(new_str)		# 结果:"54321"

my_list = [1, 2, 3, 4, 5]
new_list = my_list[3:1:-1]	# 从下标3开始,到下标1(不含)结束,步长-1(倒序)
print(new_list)		# 结果:[4, 3]

my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:1:-2] 	# 从头(最后)开始,到下标1(不含)结束,步长-2(倒序)
print(new_tuple)		# 结果:(5, 3)

可以看到,这个操作对列表、元组、字符串是通用的

同时非常灵活,根据需求,起始位置,结束位置,步长(正反序)都是可以自行控制的

6.数据容器:set(集合)

1.集合的特点

可以理解为数学中的集合,概念

  1. 确定性:集合中的元素都是确定的。
  2. 互异性:集合中的元素都是不同的。
  3. 无序性:集合中的元素没有特定的顺序

我们目前接触到了列表、元组、字符串三个数据容器了。基本满足大多数的使用场景。为何又需要学习新的集合类型呢?

通过特性来分析:列表可修改、支持重复元素且有序, 元组、字符串不可修改、支持重复元素且有序

有没有看出一些局限?

局限就在于:它们都支持重复元素。如果场景需要对内容做去重处理,列表、元组、字符串就不方便了。

而集合,最主要的特点就是:不支持元素的重复(自带去重功能)、并且内容无序

和列表、元组、字符串等定义基本相同:

  • 列表使用:[]
  • 元组使用:()
  • 字符串使用:""
  • 集合使用:{}

集合有如下特点:

  1. 可以容纳多个数据
  2. 可以容纳不同类型的数据(混装)
  3. 数据是无序存储的(不支持下标索引)
  4. 不允许重复数据存在
  5. 可以修改(增加或删除元素等)
  6. 支持for循环

2.集合的定义

基本语法:

python 复制代码
#定义集合字面量
{元素,元素,......}
#定义集合变量
变量名称 = {元素,元素,......}
#定义空集合
变量名称 = set()
python 复制代码
set1 = {1,2,3,4,1,1,2,3,5}
print(set1)
#结果
{1, 2, 3, 4, 5}

3.集合的常见操作

首先,因为集合是无序的,所以集合不支持:下标索引访问

但是集合和列表一样,是允许修改的,所以我们来看看集合的修改方法

  1. 添加新元素

    语法:集合.add(元素)。将指定元素,添加到集合内

    结果:集合本身被修改,添加了新元素

    python 复制代码
    set1 = {1,2}
    set1.add(3)
    print(set1)	#结果:{1,2,3}
    #注意:一次只能添加一个新元素
  2. 移除元素

​ 语法:集合.remove(元素),将指定元素,从集合内移除

​ 结果:集合本身被修改,移除了元素

python 复制代码
set1 = {1,2,3}
set1.remove(3)
print(set1)	#结果:{1,2}
  1. 从集合中随机取出元素

​ 语法:集合.pop(),功能,从集合中随机取出一个元素

​ 结果:会得到一个元素的结果。同时集合本身被修改,元素被移除

python 复制代码
set1 = {1,2,3}
set2 = set1.pop()
print(set1)		#结果:{2, 3}
print(set2)		#结果:1
  1. 清空集合

    语法:集合.clear(),功能,清空集合

    结果:集合本身被清空

py 复制代码
set1 = {1,2,3}
set1.clear()
print(set1)	#结果:set()  空集合
  1. 取出2个集合的差集

    语法:集合1.difference(集合2),

    功能:取出集合1和集合2的差集(集合1有而集合2没有的)

    结果:得到一个新集合,集合1和集合2不变

python 复制代码
set1 = {1,2,3}
set2 = {1,5,6}
set3 = set1.difference(set2)
print(set1)
print(set2)
print(set3)
#结果:
{1, 2, 3}
{1, 5, 6}
{2, 3}
  1. 消除2个集合的差集

    语法:集合1.difference_update(集合2)

    功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素。

    结果:集合1被修改,集合2不变

python 复制代码
set1 = {1,2,3}
set2 = {1,5,6}
set1.difference_update(set2)

print(set1)
print(set2)
#结果:
{2, 3}
{1, 5, 6}
  1. 2个集合合并

    语法:集合1.union(集合2)

    功能:将集合1和集合2组合成新集合

    结果:得到新集合,集合1和集合2不变

python 复制代码
set1 = {1,2,3}
set2 = {1,5,6}
set3 = set1.union(set2)

print(set3)	#结果:{1, 2, 3, 5, 6}
print(set1) #结果:{1, 2, 3}
print(set2) #结果:{1, 5, 6}
  1. 查看集合的元素数量

    语法:len(集合)

    功能:统计集合内有多少元素

    结果:得到一个整数结果

python 复制代码
set1 = {1,2,3}
print(len(set1))	#结果:3
  1. for循环遍历

    要注意:集合不支持下标索引,所以也就不支持使用while循环。

python 复制代码
set1 = {1,2,3}
for i in set1:
    print(i)
#结果:
1
2
3

集合常用功能总结

编号 操作 说明
1 集合.add(元素) 集合内添加一个元素
2 集合.remove(元素) 移除集合内指定的元素
3 集合.pop() 从集合中随机取出一个元素
4 集合.clear() 将集合清空
5 集合1.difference(集合2) 得到一个新集合,内含2个集合的差集原有的2个集合内容不变
6 集合1.difference_update(集合2) 在集合1中,删除集合2中存在的元素集合1被修改,集合2不变
7 集合1.union(集合2) 得到1个新集合,内含2个集合的全部元素原有的2个集合内容不变
8 len(集合) 得到一个整数,记录了集合的元素数量

综合练习

有如下列表对象:my_list = [1, 2,1,2,"A","B","A"]

请:

  • 定义一个空集合
  • 通过for循环遍历列表
  • 在for循环中将列表的元素添加至集合
  • 最终得到元素去重后的集合对象,并打印输出
python 复制代码
my_list = [1, 2, 1, 2, "A", "B", "A"]
set1 = set()
for i in my_list:
    set1.add(i)
print(set1)
#结果:
{1, 2, 'A', 'B'}

7.数据容器:dict(字典、映射)

1.字典的含义

生活中的字典:

通过【字】 ,就能找到对应的【含义】。

所以,我们可以认为,生活中的字典就是记录的一堆:【字】:【含义】【字】:【含义】...【字】:【含义】

Python中字典和生活中字典十分相像:

生活中的字典 Python中的字典
【字】:【含义】 Key: Value

老师有一份名单,记录了学生的姓名和考试总成绩。

现在需要将其通过Python录入至程序中,并可以通过学生姓名检索学生的成绩。

使用字典最为合适:

可以通过Key(学生姓名),取到对应的Value(考试成绩)。

所以,为什么使用字典? 因为可以使用字典,实现用key取出Value的操作

2.字典的定义

字典的定义,同样使用{},不过存储的元素是一个个的:键值对,如下语法:

python 复制代码
#定义字典字面量
{key:value,key:value,......}
#定义字典变量
mydict = {key:value,key:value,......}
#定义空字典
mydict ={}			#空字典定义方式1
mydict = dict()		#空字典定义方式2
  1. 使用{}存储原始,每一个元素是一个键值对
  2. 每一个键值对包含Key和Value(用冒号分隔)
  3. 键值对之间使用逗号分隔
  4. Key和Value可以是任意类型的数据(key不可为字典)
  5. Key不可重复,重复会对原有数据覆盖

前文中记录学生成绩的需求,可以如下记录:

python 复制代码
stu_score ={"王力鸿":99,"周杰轮":88,"林俊接":77}

1.字典同集合一样,不可以使用下标索引,但是字典可以通过Key值来取得对应的Value

python 复制代码
#语法,字典[key]可以取到对应的Value
stu_score ={"王力鸿":99,"周杰轮":88,"林俊接":77}
print(stu_score["王力鸿"]) #结果:99
print(stu_score["周杰轮"]) #结果:88
print(stu_score["林俊接"]) #结果:77

2.字典的Key和Value可以是任意数据类型(Key不可为字典)

那么,就表明,字典是可以嵌套的。

需求如下:记录学生各科的考试信息

python 复制代码
stu_score ={
    "王力鸿":{"语文":77,"数学":66,"英语":33},
    "周杰轮":{"语文":88,"数学":86,"英语":55},
    "林俊接":{"语文":99,"数学":96,"英语":66}}

嵌套字典的内容获取,如下所示:

python 复制代码
stu_score ={
    "王力鸿":{"语文":77,"数学":66,"英语":33},
    "周杰轮":{"语文":88,"数学":86,"英语":55},
    "林俊接":{"语文":99,"数学":96,"英语":66}}
print(stu_score["王力鸿"])			  #结果:{'语文': 77, '数学': 66, '英语': 33}
print(stu_score["王力鸿"]["语文"])   #结果:77
print(stu_score["周杰轮"]["英语"])   #结果:55

3.字典的常用操作

  1. 新增元素

    语法:字典[Key] = Value,结果:字典被修改,新增了元素

python 复制代码
stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}
#新增,张学油的考试成绩
stu_score['张学油'] = 66
print(stu_score) 
#结果:{'王力鸿': 99, '周杰轮': 88, '林俊接': 77, '张学油': 66}
  1. 更新元素

    语法:字典[Key] = Value,结果:字典被修改,元素被更新

    注意:字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值

python 复制代码
stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

stu_score['王力鸿'] = 66
print(stu_score)
#结果:{'王力鸿': 66, '周杰轮': 88, '林俊接': 77}
  1. 删除元素

    语法:字典.pop(Key),结果:获得指定Key的Value,同时字典被修改,指定Key的数据被删除

python 复制代码
stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

value =stu_score.pop("王力鸿")
print(stu_score)        #结果:{'周杰轮': 88, '林俊接': 77}
print(value)            #结果:99
  1. 清空字典

    语法:字典.clear(),结果:字典被修改,元素被清空

python 复制代码
stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

stu_score.clear()
print(stu_score)        #结果:{}
  1. 获取全部的key

    语法:字典.keys(),结果:得到字典中的全部Key

python 复制代码
stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

key = stu_score.keys()
print(key)        #结果:dict_keys(['王力鸿', '周杰轮', '林俊接'])
  1. 遍历字典

    语法:for key in 字典.keys()

python 复制代码
stu_score ={
   "王力鸿":99,
   "周杰轮":88,
   "林俊接":77}

keys = stu_score.keys()
for i in keys:
    print(f"学生:{i},分数:{stu_score[i]}")
#结果:学生:王力鸿,分数:99
      学生:周杰轮,分数:88
      学生:林俊接,分数:77

注意:字典不支持下标索引,所以同样不可以用while循环遍历

  1. 计算字典内的全部元素(键值对)数量

    语法:len(字典)

    结果:得到一个整数,表示字典内元素(键值对)的数量

python 复制代码
stu_score ={
   "王力鸿":99,
   "周杰轮":88,
   "林俊接":77}
print(len(stu_score))   #结果:3

总结

编号 操作 说明
1 字典[Key] 获取指定Key对应的Value值
2 字典[Key] = Value 添加或更新键值对
3 字典.pop(Key) 取出Key对应的Value并在字典内删除此Key的键值对
4 字典.clear() 清空字典
5 字典.keys() 获取字典的全部Key,可用于for循环遍历字典
6 len(字典) 计算字典内的元素数量

经过上述对字典的学习,可以总结出字典有如下特点:

  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 每一份数据是KeyValue键值对
  • 可以通过Key获取到Value,Key不可重复(重复会覆盖)
  • 不支持下标索引
  • 可以修改(增加或删除更新元素等)
  • 支持for循环,不支持while循环

练习题

有如下员工信息,请使用字典完成数据的记录。

并通过for循环,对所有级别为1级的员工,级别上升1级,薪水增加1000元

python 复制代码
people ={
    "王力鸿":{"部门":"科技部","工资":3000,"级别":1},
    "周杰轮":{"部门":"市场部","工资":5000,"级别":2},
    "林俊接":{"部门":"市场部","工资":7000,"级别":3},
    "张学油":{"部门":"科技部","工资":4000,"级别":1},
    "刘德滑":{"部门":"市场部","工资":6000,"级别":2}}
print("全体成员信息如下:")
for i in people:
    print(i,people[i])
print("涨薪后信息为:")
for j in people:
    if people[j]["级别"]==1:
        people[j]["级别"] +=1
        people[j]["工资"]+=1000
    print(j, people[j])
#运行结果:
全体成员信息如下:
王力鸿 {'部门': '科技部', '工资': 3000, '级别': 1}
周杰轮 {'部门': '市场部', '工资': 5000, '级别': 2}
林俊接 {'部门': '市场部', '工资': 7000, '级别': 3}
张学油 {'部门': '科技部', '工资': 4000, '级别': 1}
刘德滑 {'部门': '市场部', '工资': 6000, '级别': 2}
涨薪后信息为:
王力鸿 {'部门': '科技部', '工资': 4000, '级别': 2}
周杰轮 {'部门': '市场部', '工资': 5000, '级别': 2}
林俊接 {'部门': '市场部', '工资': 7000, '级别': 3}
张学油 {'部门': '科技部', '工资': 5000, '级别': 2}
刘德滑 {'部门': '市场部', '工资': 6000, '级别': 2}

数据容器对比

列表 元组 字符串 集合 字典
元素数量 支持多个 支持多个 支持多个 支持多个 支持多个
元素类型 任意 任意 仅字符 任意 Key:ValueKey:除字典外任意类型Value:任意类型
下标索引 支持 支持 支持 不支持 不支持
重复元素 支持 支持 支持 不支持 不支持
可修改性 支持 不支持 不支持 支持 支持
数据有序
使用场景 可修改、可重复的一批数据记录场景 不可修改、可重复的一批数据记录场景 一串字符的记录场景 不可重复的数据记录场景 以Key检索Value的数据记录场景

基于各类数据容器的特点,它们的应用场景如下:

  • 列表:一批数据,可修改、可重复的存储场景
  • 元组:一批数据,不可修改、可重复的存储场景
  • 字符串:一串字符串的存储场景
  • 集合:一批数据,去重存储场景
  • 字典:一批数据,可用Key检索Value的存储场景

数据容器通用操作

1.数据容器尽管各自有各自的特点,但是它们也有通用的一些操作。

首先,在遍历上:

  • 5类数据容器都支持for循环遍历
  • 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)

尽管遍历的形式各有不同,但是,它们都支持遍历操作。

2.除了遍历这个共性外,数据容器可以通用非常多的功能方法

len(容器):统计容器的元素个数

python 复制代码
my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(len(my_list))	# 结果3
print(len(my_tuple))	# 结果5
print(len(my_str))	# 结果7

max(容器):统计容器的最大元素

python 复制代码
my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(max(my_list))	# 结果3
print(max(my_tuple))	# 结果5
print(max(my_str))	# 结果o		根据ascall码表来比大小

min(容器):统计容器的最小元素

python 复制代码
my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(min(my_list))	# 结果1
print(min(my_tuple))	# 结果1
print(min(my_str))	# 结果e

3.除了下标索引这个共性外,还可以通用类型转换

list(容器):将给定容器转换为列表

**str(容器):**将给定容器转换为字符串

**tuple(容器):**将给定容器转换为元组

set(容器):将给定容器转换为集合

4.通用排序功能

python 复制代码
sorted(容器, [reverse=True])
将给定容器进行排序

注意,排序后都会得到列表(list)对象。

总览

功能 描述
通用for循环 遍历容器(字典是遍历key)
max 容器内最大元素
min() 容器内最小元素
len() 容器元素个数
list() 转换为列表
tuple() 转换为元组
str() 转换为字符串
set() 转换为集合
sorted(序列, [reverse=True]) 排序,reverse=True表示降序得到一个排好序的列表

拓展:字符串比大小

在程序中,字符串所用的所有字符如:

  • 大小写英文单词
  • 数字
  • 特殊符号(!、\、|、@、#、空格等)都有其对应的ASCII码表值

每一个字符都能对应上一个:数字的码值字符串进行比较就是基于数字的码值大小进行比较的。

字符串是按位比较,也就是一位位进行对比,只要有一位大,那么整体就大。

第七章 文件操作

1.文件的编码

思考:计算机只能识别:0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢?

答案:使用编码技术(密码本)将内容翻译成0和1存入。

编码技术即:翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容。

编码有许多,所以要使用正确的编码, 才能对文件进行正确的读写操作呢。

我们可以使用Windows系统自带的记事本,打开文件后,即可看出文件的编码是什么:

UTF-8是目前全球通用的编码格式除非有特殊需求,否则,一律以UTF-8格式进行文件编码即可。

2. 文件的读取

内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索,引入了"文件"的概念。

一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。

想想我们平常对文件的基本操作,大概可以分为三个步骤(简称文件操作三步走):① 打开文件 ② 读写文件 ③ 关闭文件

注意:可以只打开和关闭文件,不进行任何读写

open()打开函数

在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下

python 复制代码
open(name, mode, encoding)

name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8)
python 复制代码
#示例代码
f = open("D:/a.txt", "r", encoding="UTF-8")
print(type(f))		#结果:<class '_io.TextIOWrapper'>

# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定

注意:此时的fopen函数的文件对象,对象是Python中一种特殊的数据类型,拥有属性和方法,可以使用对象.属性或对象.方法对其进行访问,后续面向对象会进行详细的介绍。

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w 打开一个文件只用于写入。1.如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。2.如果该文件不存在,创建新文件。
a 打开一个文件用于追加。1.如果该文件已存在,新的内容将会被写入到已有内容之后。2.如果该文件不存在,创建新文件进行写入。

read()方法:

python 复制代码
文件对象.read(num)
#num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。

# 示例代码
f = open("D:/a.txt", "r", encoding="UTF-8")
a = f.read()
print(a)

readlines()方法:

python 复制代码
#readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
f = open('D:/a.txt')
content = f.readlines()

# ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
print(content)

# 关闭文件
f.close()
python 复制代码
#readline()方法:一次读取一行内容

f = open('D:/a.txt')

content = f.readline()
print(f'第一行:{content}')

content = f.readline()
print(f'第二行:{content}')

# 关闭文件
f.close()
python 复制代码
#for循环读取文件行

for line in open("D:/a.txt", "r"):
    print(line)

# 每一个line临时变量,就记录了文件的一行数据

close() 关闭文件对象

python 复制代码
f = open("D:/a.txt", "r")

f.close()

# 最后通过close,关闭文件对象,也就是关闭对文件的占用
# 如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用。

with open 语法

python 复制代码
with open("python.txt", "r") as f:
    f.readlines()

# 通过在with open的语句块中对文件进行操作
# 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
操作 功能
文件对象 = open(file, mode, encoding) 打开文件获得文件对象
文件对象.read(num) 读取指定长度字节不指定num读取文件全部
文件对象.readline() 读取一行
文件对象.readlines() 读取全部行,得到列表
for line in 文件对象 for循环文件行,一次循环得到一行数据
文件对象.close() 关闭文件对象
with open() as f 通过with open语法打开文件,可以自动关闭

3.文件的写入

python 复制代码
# 1. 打开文件
f = open('D:/a.txt', 'w')

# 2.文件写入
f.write('hello world')

# 3. 内容刷新
f.flush()	#可以直接f.close关闭,自动刷新

注意:

  • 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区。
  • 当调用flush的时候,内容会真正写入文件。
  • 这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)。

写操作注意

  • 文件如果不存在,使用"w"模式,会创建新文件
  • 文件如果存在,使用"w"模式,会将原有内容清空

总结

  1. 写入文件使用open函数的"w"模式进行写入

  2. 写入的方法有:

    wirte(),写入内容

    flush(),刷新内容到硬盘中

  3. 注意事项:

    w模式,文件不存在,会创建新文件

    w模式,文件存在,会清空原有内容

    调用close(),自动使用flush()方法的功能

4.文件的追加

python 复制代码
# 1. 打开文件,通过a模式打开即可
f = open('python.txt', 'a')

# 2.文件写入
f.write('hello world')

# 3. 内容刷新
f.flush()

注意:

  • a模式,文件不存在会创建文件
  • a模式,文件存在会在最后,追加写入文件

总结

  1. 追加写入文件使用open函数的"a"模式进行写入

  2. 追加写入的方法有(和w模式一致):

    wirte(),写入内容

    flush(),刷新内容到硬盘中

  3. 注意事项:

    a模式,文件不存在,会创建新文件

    a模式,文件存在,会在原有内容后面继续写入

    可以使用"\n"来写出换行符

5.文件备份案例

需求:有一份账单文件,记录了消费收入的具体记录,内容如下:

python 复制代码
name,date,money,type,remarks

周杰轮,2022-01-01,100000,消费,正式
周杰轮,2022-01-02,300000,收入,正式
周杰轮,2022-01-03,100000,消费,测试
林俊节,2022-01-01,300000,收入,正式
林俊节,2022-01-02,100000,消费,测试
林俊节,2022-01-03,100000,消费,正式
林俊节,2022-01-04,100000,消费,测试
林俊节,2022-01-05,500000,收入,正式
张学油,2022-01-01,100000,消费,正式
张学油,2022-01-02,500000,收入,正式
张学油,2022-01-03,900000,收入,测试
王力鸿,2022-01-01,500000,消费,正式
王力鸿,2022-01-02,300000,消费,测试
王力鸿,2022-01-03,950000,收入,正式
刘德滑,2022-01-01,300000,消费,测试
刘德滑,2022-01-02,100000,消费,正式
刘德滑,2022-01-03,300000,消费,正式

将内容复制并保存为 bill.txt文件

我们现在要做的就是:

  • 读取文件
  • 将文件写出到bill.txt.bak文件作为备份
  • 同时,将文件内标记为测试的数据行丢弃

实现思路:

  1. open和r模式打开一个文件对象,并读取文件
  2. open和w模式打开另一个文件对象,用于文件写出
  3. for循环内容,判断是否是测试不是测试就write写出,是测试就continue跳过
  4. 将2个文件对象均close()
python 复制代码
# 1. 打开文件
fr = open('D:/bill.txt', 'r', encoding='UTF-8')
fw = open('D:/bill.txt.bak', 'w', encoding='UTF-8')
#2.写入文件
for line in fr:
    line = line.strip()         #去掉前后空格
    if line.split(",")[4] == "测试":#
        continue
    fw.write(line)
    fw.write("\n")  #因为前面对内容进行了strip()操作,所以要手动的写出换行符
# 3. 关闭,内容刷新
fw.close()
fr.close()

第八章 Pyhton异常、模块、包

1.异常

当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的=="异常",== 也就是我们常说的BUG

异常演示:

例如:以r方式打开一个不存在的文件。

c++ 复制代码
f = open('linux.txt', 'r')

2.异常捕获

世界上没有完美的程序,任何程序在运行的过程中,都有可能出现:异常,也就是出现bug,导致程序无法完美运行下去。

我们要做的,不是力求程序完美运行。而是在力所能及的范围内,对可能出现的bug,进行提前准备、提前处理。

这种行为我们称之为:异常处理(捕获异常)

为什么需要捕获异常?

当我们的程序遇到了BUG, 那么接下来有两种情况:

① 整个程序因为一个BUG停止运行

② 对BUG进行提醒, 整个程序继续运行

显然在之前的学习中, 我们所有的程序遇到BUG就会出现①的这种情况, 也就是整个程序直接奔溃.但是在真实工作中, 我们肯定不能因为一个小的BUG就让整个程序全部奔溃, 也就是我们希望的是达到② 的这种情况那这里我们就需要使用到捕获异常捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。

1.捕获常规异常---基本语法

这个基本异常捕获已经可以捕获全部异常,第四点没必要用

c++ 复制代码
try:
    可能发生错误的代码
except:
    如果出现异常执行的代码
python 复制代码
# 1.基本捕获语法
try:
    f = open("D:/abc.txt", "r", encoding="UTF-8")
except:
    print("出现异常了,因为文件不存在,我将open的模式,改为w模式去打开")
    f = open("D:/abc.txt", "w", encoding="UTF-8")

2.捕获指定异常

python 复制代码
# 2.捕获指定的异常
try:
    print(name)
    # 1 / 0
except NameError as e:
    print("出现了变量未定义的异常")
    print(e)

① 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。 ② 一般try下方只放一行尝试执行的代码。

把捕获异常的原因存到e变量里面,打印出来

3.捕获多个异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。

python 复制代码
# 3.捕获多个异常
try:
    # 1 / 0
    print(name)
except (NameError, ZeroDivisionError) as e:
    print("出现了变量未定义 或者 除以0的异常错误")
# 未正确设置捕获异常类型,将无法捕获异常

4.捕获所有异常

else表示的是如果没有异常要执行的代码。

python 复制代码
try:
    f = open("D:/123.txt", "r", encoding="UTF-8")
except Exception as e:
    print("出现异常了")
    f = open("D:/123.txt", "w", encoding="UTF-8")
else:
    print("好高兴,没有异常。")

5.异常的finally

finally表示的是无论是否异常都要执行的代码,例如关闭文件。

python 复制代码
try:
    f = open("D:/123.txt", "r", encoding="UTF-8")
except Exception as e:
    print("出现异常了")
    f = open("D:/123.txt", "w", encoding="UTF-8")
else:
    print("好高兴,没有异常。")
finally:
    print("我是finally,有没有异常我都要执行")
    f.close()

3.异常的传递

异常是具有传递性的。

当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常会传递到函数func02, 当func02也没有捕获处理这个异常的时候main函数会捕获这个异常, 这就是异常的传递性。

提示: 当所有函数都没有捕获异常的时候, 程序就会报错

利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候, 就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递到main函数中, 这样就可以确保所有的异常都会被捕获

4.python模块

Python 模块(Module),是一个 Python 文件,以 .py 结尾. 模块能定义函数,类和变量,模块里也能包含可执行的代码。

模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现和时间相关的功能就可以使用time模块我们可以认为一个模块就是一个工具包, 每一个工具包中都有各种不同的工具供我们使用,进而实现各种不同的功能。

**大白话:**模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用(导入模块去使用)

1.模块导入方式

模块在使用前需要先导入 导入的语法如下:

python 复制代码
[form 模块名] import [模块|类|变量|函数|*][as 别名]

常用的组合形式如:

  1. import 模块名
  2. from 模块名 import 类、变量、方法等
  3. from 模块名 import *
  4. import 模块名 as 别名
  5. from 模块名 import 功能名 as 别名

基本语法:

1.import模块名

import会把里面所有的模块都会导入进来

python 复制代码
import 模块名
import 模块名1,模块名2

模块名.功能名()
python 复制代码
# 导入时间模块
import time
print("开始") 
time.sleep(1)# 让程序睡眠1秒(阻塞)
print("结束")

2.from 模块名 import 功能名

因为导入的模块里面的函数不一定都会用上,所以只需要导入用到的即可

python 复制代码
from 模块名 import 功能名

功能名()
python 复制代码
# 导入时间模块中的sleep方法
from time import sleep
print("开始")# 让程序睡眠1秒(阻塞)
sleep(1)
print("结束")

**3.from 模块名 import ***

导入模块的全部功能,与第一个一样,区别在于,不用加 . 了。

python 复制代码
from 模块名 import *

功能名()
python 复制代码
# 导入时间模块中所有的方法
from time import *
print("开始")# 让程序睡眠1秒(阻塞)
sleep(1)
print("结束")

2.as定义别名

可以把一些长模块名重命名为短的,,方便

基本语法:

python 复制代码
# 模块定义别名
import 模块名 as 别名

# 功能定义别名
from 模块名 import 功能 as 别名

案例:

python 复制代码
# 模块别名
import time as tt
tt.sleep(2)
print('hello')

# 功能别名
from time import sleep as sl
sl(2)
print('hello')

5.自定义模块

Python中已经帮我们实现了很多的模块. 不过有时候我们需要一些个性化的模块, 这里就可以通过自定义模块实现, 也就是自己制作一个模块。

**案例:**新建一个Python文件,命名为my_module1.py,并定义test函数

注意: 每个Python文件都可以作为一个模块,模块的名字就是文件的名字. 也就是说自定义模块名必须要符合标识符命名规则

python 复制代码
# 导入不同模块的同名功能
from my_module1 import test
from my_module2 import test
test(1, 2)

注意事项:当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能。

6.测试模块

在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如,在my_module1.py文件中添加测试代码test(1,1)

python 复制代码
#my_module1.py
#当其他文件调用这个模块时,会从上到下运行一遍,这个时候test函数就会被运行,但是这个文件我又不想删除,以后想要做测试用,那么我应该怎么做呢
def test(a, b):
    print(a + b)

test(1, 1)
python 复制代码
#my_module1.py
def test(a, b):
    print(a + b)

# 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行test函数调用
if __name__ == '__main__':
    test (1, 1)

在每个文件中都有一个内部变量name ,当我在运行这个文件时,他就是main函数,但是如果是被其他文件调用过来的,则不是。

7.__ all __

如果一个模块文件中有__all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素

__all__变量可以控制import *的时候哪些功能可以被导入

8.自定义包

基于Python模块,我们可以在编写代码的时候,导入许多外部代码来丰富功能。

但是,如果Python的模块太多了,就可能造成一定的混乱,这个时候就可以通过Python包的功能来管理。

当我创建软件包时,会自动生成init.py文件

包的作用: 当我们的模块文件越来越多时,包可以帮助我们管理这些模块, 包的作用就是包含多个模块,但包的本质依然是模块

什么是包?

从物理上看,包就是一个文件夹,在该文件夹下包含了一个 init.py 文件,该文件夹可用于包含多个模块文件

从逻辑上看,包的本质依然是模块

操作流程

1.新建软件包

2.软件包与文件夹的区别,会在下面自动生成init.py(一般为空)。

python 复制代码
"""
演示自定义模块1
my_module1.py
"""

def info_print1():
    print("我是模块1的功能函数代码")
python 复制代码
"""
自定义模块2
my_module2.py
"""

def info_print2():
    print("我是模块2的功能函数代码")
python 复制代码
# 创建一个包
# 导入自定义的包中的模块,并使用
#第一种导入方法
import my_package.my_module1
import my_package.my_module2

my_package.my_module1.info_print1()
my_package.my_module2.info_print2()

#第二种导入方法
from my_package import my_module1
from my_package import my_module2
#可以合起来写from my_package import my_module1,my_module2
my_module1.info_print1()
my_module2.info_print2()

#第三种导入方法
from my_package.my_module1 import info_print1
from my_package.my_module2 import info_print2
info_print1()
info_print2()

控制导入模块的行为

from 包名 import *

注意:必须在__init__.py文件中添加__all__ = [],控制允许导入的模块列表

9.安装第三方包

我们知道,包可以包含一堆的Python模块,而每个模块又内含许多的功能。

所以,我们可以认为:一个包,就是一堆同类型功能的集合体。

在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,

如:

  1. 科学计算中常用的:numpy包
  2. 数据分析中常用的:pandas包
  3. 大数据计算中常用的:pyspark、apache-flink包
  4. 图形可视化常用的:matplotlib、pyecharts
  5. 人工智能常用的:tensorflow等

这些第三方的包,极大的丰富了Python的生态,提高了开发效率。但是由于是第三方,所以Python没有内置,所以我们需要安装它们才可以导入使用哦。

第三方包的安装非常简单,我们只需要使用Python内置的pip程序即可。

安装:在命令提示符程序,输入:pip install 包名称即可通过网络快速安装第三方包。

pip的网络优化:

由于pip是连接的国外的网站进行包的下载,所以有的时候会速度很慢。

我们可以通过如下命令,让其连接国内的网站进行包的安装:

python 复制代码
 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

https://pypi.tuna.tsinghua.edu.cn/simple 是清华大学提供的一个网站,可供pip程序下载第三方包

  • PyCharm安装第三方包
相关推荐
罗政2 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第12章 结束
java·开发语言·pdf
匹马夕阳3 分钟前
详细对比JS中XMLHttpRequest和fetch的使用
开发语言·javascript·ecmascript
月巴月巴白勺合鸟月半4 分钟前
一个特别的串口通讯
开发语言·串口通讯
乄北城以北乀9 分钟前
第1章 R语言中的并行处理入门
开发语言·分布式·r语言
全栈老实人_19 分钟前
农家乐系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
工程师焱记20 分钟前
【docker系列】打造个人私有网盘zfile
经验分享
lmxnsI20 分钟前
docker使用笔记
笔记·docker·容器
Tester_孙大壮34 分钟前
Python爬虫技术科普
开发语言·爬虫·python
点点滴滴的记录38 分钟前
Java的CompletableFuture实现原理
java·开发语言·javascript
程序猿online41 分钟前
nvm安装使用,控制node版本
开发语言·前端·学习