一.pycharm使用入门
1.creat project
-
虚拟环境:基于系统环境copy的一个环境,python的版本是依据于系统环境的python版本
-
系统环境:
-
对比于用户来说,是不受制用户登录的限制,所有的用户都可以使用
-
对比于虚拟环境,是相互独立的,互不干扰--比如我在系统环境中安装了一个python的依赖包,虚拟环境是不会对应安装的(不存在的,需要单独去安装)
-
在pycharm项目中。可以随意更换项目所依赖的环境
-
所有的python项目都是需要依据环境来运行的--python脚本
-
项目和python环境是可以分开的,只不过是受制于python环境中的依赖包
-
项目的内容不要放在环境的目录下面
-
-



pycharm使用系统环境,不会去创建venv目录


pycharm创建项目之后
first:是命名的项目名称
vevn文件夹:虚拟环境的文件夹(不懂的话,千万不要乱动)
新建文件的时候,需要右键项目名称的文件夹,然后创建文件 -- 千万不要在venv目录下面创建文件
2.安装依赖包
-
pip install 依赖包
pip install 依赖包名称 -i 镜像源地址
安装在系统环境就在系统环境,虚拟环境没有;安装在虚拟环境同理



如果需要安装历史版本,就采用以下方式:
-
点击右边的 Specify version 勾选框
-
点击右边的下拉框按钮
-
选择所需要的版本
-
点击Install Package
注意:如果网络不太好的情况下,可能出不来版本信息,那么就采用命令下载的方式
国内镜像源:
https://pypi.douban.com/simple/ 豆瓣 https://mirrors.aliyun.com/pypi/simple/ 阿里 https://pypi.hustunique.com/simple/ 华中理工大学 https://pypi.sdutlinux.org/simple/ 山东理工大学 https://pypi.mirrors.ustc.edu.cn/simple/ 中国科学技术大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 清华
查看某一个依赖包安装的信息,执行命令:pip show 依赖包的名字:
pip show pytest
怎么把项目所需要的环境,传递给同事 -- 统一依赖包的版本(python的版本也要一样)
\# 示例:导出的文件名称可以自定义 pip freeze > request.txt
request.txt :自己定义的文件名
-
通过pycharm打开项目文件,然后创建一个虚拟环境
但凡是图标带V的,都是指代的虚拟环境,反之表示系统环境
![]()


2.拿到 request.txt 文件之后,执行命令,会按照request.txt 文件的要求,去下载依赖包的相关信息:
\# 建议加上国内的镜像源 pip install -r output.txt -i https://mirrors.aliyun.com/pypi/simple/
cmd执行方式
二.python的输入输出、数据类型
1.输入输出
#输出 print
print("hello world")
"""
注释
单引号和双引号没区别,但单引号和双引号要成对出现
"""
'''
注释
多行注释:鼠标选中要注释的内容,然后 ctrl + /
格式化代码:ctrl + alt + L (L=shift +l)
直接复制上一行代码:ctrl + D
'''
#输入 input
a=input("请输入密码")
print(a)
print("请输入您的密码:"+input())
"""
程序是有开始,有结束的---绝大数情况下
程序的运行规则:从上到下,由内而外----重点
"""
2.格式化输出
"""
方式一:
使用%d、%f、%s 进行占位,后面的输出内容使用 %(value1, value2, value3)
%d : 整数
%f:小数/浮点数
%s:字符串
"""
print("""
=====自我介绍=====
name: %s
addr: %s
age: %d
sal: %f
""" % ("七夜老师", "湖南长沙", 18, 1001))
"""
方式二:
直接使用 {} 进行占位,后面接 .format(value1, value2),
前面设置了几个占位符{},后面就需要传入几个值
"""
print("""
=====自我介绍=====
name: {}
addr: {}
age: {}
sal: {}
""".format("七夜老师", "湖南长沙", 18, 1001))
"""
方式三:在字符串引号前面加个f(只适用于变量)
然后字符串中间用{}
把变量的名称括起来
示例:
"""
name, age, sex = "七夜老师", 18, "man"
print(f"名字:{name}")
print(f"年龄:{age}")
print(f"性别:{sex}")
# 打印的结果
"""
名字:七夜老师
年龄:18
性别:man
"""
3.数字类型
常见的数字类型:
-
整数: 0-9组成的数字 int
-
浮点数:整数 + 小数点 + 小数 float
-
布尔值:对或者错 真(True)或者假(False),如果是做计算的话,True == 1,False == 0 bool
-
复数:实数 + 虚数,complex,比如:0.99j
type()用来获取数据的类型
示例:
print(type(9)) # <class 'int'> print(type(1 > 2)) # <class 'bool'> print(type(3 < 1)) # <class 'bool'> print(type(100 + 0.99j)) # <class 'complex'>
字符串类型
print("True")
print(True)
带""的都属于字符串类型
4.变量的应用
定义:在计算机中,能够指代某个值或者结果的东西 -- 变量
用一个英文单词/字母,去代替某些值的时候,可以直接把这个单词/字母拿过来使用 -- 这个单词/字母称之为变量
举例:求圆的面积公式 S=π*r²,S为变量
num1=2 #在计算机中,=号,一个=号表示赋值,把最右边的值,赋值给左边的变量 num2=7 # ==号,两个便是判断是否等于的意思 # + - * / 对于python中的加减乘除
注意:python中,定义变量的时候,可以直接赋值,不需要提前去定义类型(区别:java语言)
多个变量赋值:
连续赋值:多个变量使用同一个值
a = b = 10 print(a) print(b) print(id(a))#输出a b的内存地址,值一样,地址相同 print(id(b))
多个变量使用多个值
name, age, sex = "七夜老师", 18, "man" print(name) print(age) print(sex)
一个变量赋多个值:* 号进行接收----* 号表示解包
a, b, *c = 1, 2, 3, 4, 5, 6, 7, 8, 9
print(f"a收到的值:{a}")
print(f"b收到的值:{b}")
print(f"c收到的值:{c}")
只能有一个* 号
5.类型转换
字符串--->整数 int("字符串(注意:数字类型)")
字符串--->浮点数 float()
字符串--->布尔值 boot()
字符串--->字符串 str()
示例一:
str1 = "100" a = int(str1) print("str1的数据类型:",type(a)) # <class 'int'>示例二:
# 错误的示例 str2 = "3.14" a = int(str2) print("str2的数据类型:",type(a)) # 正确的写法 str2 = "3.14" a = float(str2) b = int(a) print(b) print("str2的数据类型:",type(b)) #浮点类型字符串不能直接转换为int类型 不进行四舍五入
课后作业
1.输入两个数字,并且同时打印出来
2.请将字符串"3.1415926"转为浮点型并且乘以2,再转为整型进行输出
3.【项目】利用上课学过的知识完成以下需求实战:(利用format完成占位输出)
# 需求:
1)打印"欢迎来到xx同学的python书店" # 2)定义变量接收(book_name:"python",book_author:"七夜",book_num:10,book_price:77) # 3)最后格式化打印: # 同学你好,你需要购买的书籍名称为: {} ,价格为: {}元, # 作者为: {} , 当前库存数量为: {} 本,祝你学习愉快!~~
print("----欢迎来到ljl同学的python书店----") book_name = input("请输入书籍的名称:") book_author = input("请输入书籍的作者:") book_num = input("请输入书籍的库存数量:") book_price = input("请输入书籍的售卖价格:") print(""" 同学你好,你需要购买的书籍名称为: {} ,价格为: {}元, 作者为: {} , 当前库存数量为: {} 本,祝你学习愉快!~~ """.format(book_name, book_price, book_author, book_num))
三、python中的运算符、条件分支结构、循环结构
运算符
1.算数运算符
常见的运算符: 加(+) 减(-) 乘(*) 除( /)
print(num1 + num2) print(num1 - num2) print(num1 * num2) print(num1 / num2) # 问:运算的结果? 坑 15 5 50 2.0
注意:在做除法运算的时候,会出现一个小数点 -- 浮点数的类型
复杂的用法:
1)求余数: %
举个例子:现在有10个文件,分给3个人,请问余数为多少? -- 1
num1 = 10
num3 = 3
print("所得到的余数为: {}".format(num1 % num3))
# 运算的结果 所得到的余数为: 1
2)整除(只会取整数): //
num1 = 10
num3 = 3
print("整除后的结果为: {}".format(num1 // num3))
# 整除后的结果为: 3
3)幂(次方): **
num1 = 10
num3 = 3
print("次方得到的结果为: {}".format(num1 ** num3))
# 次方得到的结果为: 1000
特殊的用法:
举例:如果一半是数字,一半不是?
1)str类型 和 str类型:
两个str类型的值进行加法运算 -- 拼接(不要默认给英文单词之间,加上空格)
str1 = "hello"
str2 = "world"
print("两个str类型的值,进行加法计算的结果:{}".format(str1 + str2))
# 两个str类型的值,进行加法计算的结果:helloworld
2)str类型 和 数字类型:
多次打印str类型,打印的次数由数字类型决定
str1 = "hello"
num4 = 3
print(str1+num4)
#str和数字类型不能相加,可以相乘
print("str类型和数字类型,进行乘法运算:{}".format(str1 * num4))
# str类型和数字类型,进行乘法运算:hellohellohello
示例:
print("-" * 100) # ----------------------------------------------------------------------------------------------------
其他多种类型运算:
1)int类型 和 float类型:有可能存在一个问题 -- 精准度丢失(python的语言问题,不需要额外关注)
data = 3
f2 = 2.111
print("int类型 + float类型,得到的结果:{}".format(data + f2))
# int类型 + float类型,得到的结果:5.111000000000001
2)bool类型 和 int类型:
bool类型,在做计算的时候,True == 1, False == 0
bol = True
# 直接定义的bool类型 data = 3
# 非0为true
print("bool类型 + int类型,得到的结果:{}".format(bol + data))
# bool类型 + int类型,得到的结果:4
2. 比较运算符
包含:大于、小于、等于、不等于、大于等于、小于等于
返回的结果:bool值,True、False
等于: ==
不等于:!=(英文格式)
大于等于:>=
小于等于:<=
a = 10
b = 5
print(f"大于:{a > b}")
print(f"小于:{a < b}")
print(f"等于:{a == b}")
# 两个=号,表示判断是否相等
print(f"不等于:{a != b}")
# != 表示不等于
print(f"大于等于:{a >= b}") print(f"小于等于:{a <= b}")
# 结果: 大于:True 小于:False 等于:False 不等于:True 大于等于:True 小于等于:False
3.赋值运算符
单个的=号,表示赋值的意思
赋值:把=号,右边的值,赋值给左边
a = 10
a += 5 # 属于简写:a = a + 5 的结果
print(f"a += 5 的结果:{a}")
# 结果:a += 5 的结果:15
a -= 5
a *= 5
a /= 5
注意事项:程序的执行顺序(从上到下,由内而外)
a = 10
a += 5
a *= 5
print(f"a += 5 的结果:{a}")
# a += 5 的结果:75
4.逻辑运算符
返回的结果:bool值,True、False
包括:与(and) 或(or) 非(not)
定义:
与运算:所有逻辑都是True,最终结果才是True -- 同真为真,有假为假
或运算:只要有一个逻辑是True最终结果就是True -- 同假为假,有真为真
非运算:不管别人是正确还是错,他一定要反对 -- 杠精,相对
示例:
a = True
b = False
print(f"与运算:{a and b}")
# False
print(f"或运算:{a or b}")
# True
print(f"非运算:{not b}")
# True
练习:
1)优先级:比较 > 逻辑
print(1 > 2 and 4 > 3) # False # False and True # False print(1 > 2 or 4 > 3) # True # False or True # True
答:True and False,与运算:所有逻辑都是True,最终结果才是True -- 同真为真,有假为假
2)优先级:not > and > or
print(True and False or True and not False) # True # True and False or True and True # False or True # True
3)优先级:算数 > 比较 > 逻辑(not > and > or)
print(1 + 1 > 1 + 2 and 3 + 2 < 3 - 1 or 5 and not True) # False # 2 > 3 and 5 < 2 or 5 and not True # False and False or 5 and not True # False and False or 5 and False # False or False # False
提问:5 and False,这个地方的值为多少?
答:False
False or 5 输出结果为 :5
-
与运算:所有逻辑都是True,最终结果才是True -- 同真为真,有假为假
-
做判断的时候:非0则为True
5.成员运算符
定义:判断指定内容是否包含在某个内容中 包含关系
返回的结果:bool值,True、False
in:存在(包含)
not in:不存在(不包含)
示例:
str1 = "qiyelaoshi"
print("判断'qiye'是否存在str1变量里面:{}".format('qiye' in str1))
# True
print("判断'qiye'是否存在str1变量里面:{}".format('qiye' not in str1))
# False
注意:
1)bool类型的数据,是不能够做成员运算符的计算:
bol = True print("'T'是否存在bol变量里面:".format('T' in bol))
# 报错信息:argument of type 'bool' is not iterable
2)数字类型的数据,是不能够做成员运算符的计算:
num1 = 123 #数字是一个整体,无法去判断包含还是不包含 print(1 in num1) # 报错信息:argument of type 'int' is not iterable
条件分支结构
1.单向分支
语法结构:
if 判断条件(运算符、bool值):
逻辑代码(1. 如果条件满足 -- True,就执行这部分逻辑代码; 2. 如果不满足,就跳过这段逻辑代码,不执行)
示例:如果用户输入了'admin'的内容,那么输出'欢迎管理员登录'
name = input("提示用语[请输入您的登录账号]: ")
# 用变量接收输入的值
if name == 'admin':
# 判断的条件:拿[输入的内容]和[预期结果]作是否相等的判断
print("欢迎管理员登录")
2.双向分支
如果条件不满足,那么就执行另一块代码,这两块代码一定不会同时执行
语法结构:
if 判断条件(运算符、bool值):
逻辑代码(1. 如果条件满足 -- True,就执行这部分逻辑代码; 2. 如果不满足,就跳过这段逻辑代码,不执行)
else:
逻辑代码(if条件不满足的情况下,才会执行else,如果满足if条件,则跳过else代码块,不执行)
示例:排除特殊性的场景,如果你不是一个男孩子,那么一定是一个女孩子
sex = input("请问您是男孩子么?请输入:yes 或 no:")
if sex == 'yes':
print("那你应该喜欢打篮球")
else:
print("那你应该喜欢口红")
3.多向分支
存在多个条件判断,只要满足一个条件,就不会去执行其他条件
语法结构:
if 判断条件1(运算符、bool值):
#逻辑代码1(1. 如果条件满足 -- True,就执行这部分逻辑代码; 2. 如果不满足,就跳过这段逻辑代码,不执行)
elif 判断条件2:
#逻辑代码2(1. 如果条件满足 -- True,就执行这部分逻辑代码; 2. 如果不满足,就跳过这段逻辑代码,不执行)
elif 判断条件3:
#逻辑代码3(1. 如果条件满足 -- True,就执行这部分逻辑代码; 2. 如果不满足,就跳过这段逻辑代码,不执行) ... ...
else:
#逻辑代码(如果以上条件都不满足,才会执行else,如果满足以上的任意条件,则跳过else代码块,不执行)
示例:买票的条件
\1. 60以上,3以下 [免票]
\2. 12 - 59 成人票[全票]
\3. 4 - 11 儿童票[半票]
age = int(input("请输入您的年龄:"))
# int(需要转换的数据)
if age >= 60 or age <= 3:
# [免票]的区间
print("[免票]")
elif age >= 12 and age < 60:
# 成人票[全票]的区间
print("成人票[全票]")
elif age >= 4 and age < 12:
# 儿童票[半票]
print("儿童票[半票]")
注意:input()方法接收的值,都是str类型
4.if判断条件
理论上说 if 后面可以接任意条件,只要它的结果是bool值就行
使用的情况:
-
比较: > < ==
-
逻辑: and or not
-
成员:in not in
-
数学: + - * /
-
直接使用bool值
示例:
\# 1)
if 1 - 1:
# 1 - 1 = 0,非0则为True,0则为False
print("if打印的内容")
else:
print("else打印的内容")
# 2)
b = input("请输入文字:")
if 'qiye' in b:
print("if打印的内容")
else:
print("else打印的内容")
# 3)
a = int(input("请输入数字:"))
if a - 1:
# 1 - 1 = 0
print("if打印的内容")
else:
print("else打印的内容")
5.子分支
if的嵌套,if ... else ...里面再去嵌套 if ... else ...
if 条件1:
代码块1
if 条件2:
代码块2
else:
代码块b
else:
代码块b
#if和else可以无限嵌套
示例:相亲的条件,条件1:满足180身高;条件2:满足月薪100;
hight = int(input("请输入相亲对象的身高:"))
if hight >= 180:
print("可以考虑一下")
sal = int(input("请输入相亲对象的工资:"))
if sal >= 100:
print("可以见一面")
else:
print("我还是考虑考虑吧")
else:
print("不好意思,不考虑,我要加班")
循环结构_while
1.while循环
让某段代码逻辑去反复执行,这个就叫循环,具体的执行次数,就是由条件决定的
语法结构:
while 判断条件:
逻辑代码
-
只要判断条件为True这个代码块就会反复执行,执行到代码的最后一行重新判断条件,
-
如果判断条件还是True就继续执行一次,如此反复
-
如果判断条件是False,就跳出循环
-
while是关键字(python固定设置的内容)
-
如果while的判断条件,始终满足----一直执行/死循环-----避免---改变while的条件
示例:
while True:
print("欢迎来到七夜老师的课堂!")
注意:当while的判断条件始终为True的时候,会进入死循环
不要让while的循环条件恒定,需要有办法改变它原来的条件
方式一:引用变量,让条件不会恒定,让变量可以变化,同时与while条件相结合
a = 0 # 设置一个初始值
while a < 6:
# a的取值:0、1、2、3、4、5
print("欢迎来到七夜老师的课堂!")
a += 1
# a每循环一次,就会在原有的基础上进行 +1
# 提问:会打印几次?6次
2.关键字避免死循环
break :直接终止整个循环,不去判断条件,直接结束循环
continue:遇到continue这个关键字,这个时候不去执行循环内部往下的代码(循环内部),直接重新去判断条件
区别:
continue:中断当前循环,直接执行判断条件。如果条件为True,继续执行,如果条件为False,就停止循环
break:直接中断整个循环,不去判断条件,直接循环结束
示例:
a = 10 # 设置的初始值
while a:
# a的取值为:9、8、7、6、5、4
a -= 1
if a % 2 == 0:
print(f"当前的值为偶数,此时a的值为:{a}")
continue # 中断当前循环,直接执行判断条件
if a < 5:
print(f"当a的值小于5了,直接结束循环,此时a的值为:{a}")
break
# 中断整个循环,直接结束
# 提问:当a的值为多少的时候,跳出循环?3
# 同学们的问题:为什么不是4的时候,跳出循环?
# 程序的运行顺序,从上往下,a=4时会先满足第一个if判断的时候,直接continue,重新判断条件,然后重新回到a-=1去执行,然后a=3,不满足第一个if条件不执行,就到了第二个if中执行,然后就遇到了break终止循环
课后作业
"""
1.定义两个变量num_1、num_2接收两个浮点型的数字字符串,然后进行转换,并且分别打印出加减乘除的计算结果
(涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
2.定义两个变量num_1、num_2接收两个浮点型的数字字符串,进行类型转换,然后再定义一个变量operation_symbol接收一个加减乘除的字符串,并通过if判断对两个数字进行运算和结果输出
(涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
3.结合以上条件,引用while循环,让其可以循环输入运算符号和计算结果,添加输入错误提示:"输入有误,无法识别,请重新操作",输入"exit"退出系统功能(while、continue、break)
4.一家商场在降价促销,如果购买金额50-100元(包含50和100元)之间,会给10%的折扣,如果购买金额大于100元会给20%的折扣,
编写一个程序,询问购买价格,再显示出折扣,(10%或20%,可以直接乘以0.1或者0.2)和最终价格
5.输入一个年份,输出是否为闰年。
闰年条件:能被4整除但不能被100整除,或者能被400整除但年份都是闰年
6.完成一个猜数字游戏
# 进入程序后
# 提示用户输入 要猜的数字
# 其他人输入时,提示数字大了,或者小了
# 猜到正确的"""
1.定义两个变量num_1、num_2接收两个浮点型的数字字符串,然后进行转换,并且分别打印出加减乘除的计算结果
(涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
2.定义两个变量num_1、num_2接收两个浮点型的数字字符串,进行类型转换,然后再定义一个变量operation_symbol接收一个加减乘除的字符串,并通过if判断对两个数字进行运算和结果输出
(涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
3.结合以上条件,引用while循环,让其可以循环输入运算符号和计算结果,添加输入错误提示:"输入有误,无法识别,请重新操作",输入"exit"退出系统功能(while、continue、break)
4.一家商场在降价促销,如果购买金额50-100元(包含50和100元)之间,会给10%的折扣,如果购买金额大于100元会给200%的折扣,
编写一个程序,询问购买价格,再显示出折扣,(10%或20%,可以直接乘以0.1或者0.2)和最终价格
5.输入一个年份,输出是否为闰年。
闰年条件:能被4整除但不能被100整除,或者能被400整除但年份都是闰年
6.完成一个猜数字游戏
# 进入程序后
# 提示用户输入 要猜的数字
# 其他人输入时,提示数字大了,或者小了
# 猜到正确的数字为止,提示恭喜猜对了
# (选做:可以控制每位玩家的猜数字次数,例如,一个人只能猜3次,3次猜错结束程序,显示正确的数字后,重新开始)
# (选做: 猜数字的游戏中的数字尝试让系统生成,提示:random.randint(n,m) 可以让python在n-m之间生成一个随机数)
# 7.【项目】结合今天所学的内容,对上节课的作业项目进行升级
# 模拟课堂上的project_duck,改编自己的书籍项目(包含while、break、if等知识点)
"""
# 1.定义两个变量num_1、num_2接收两个浮点型的数字字符串,然后进行转换,并且分别打印出加减乘除的计算结果
# (涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
# num_1 = float(input("请输入第一个数字:"))
# num_2 = float(input("请输入第二个数字:"))
# print("加法计算的结果为: {}".format(num_1 + num_2))
# print("减法计算的结果为: {}".format(num_1 - num_2))
# print("乘法计算的结果为: {}".format(num_1 * num_2))
# # print("除法计算的结果为: {}".format(num_1 / num_2))
# print("除法计算的结果为: {}".format(round((num_1 / num_2), 2)))
# 2.定义两个变量num_1、num_2接收两个浮点型的数字字符串,进行类型转换,然后再定义一个变量operation_symbol接收一个加减乘除的字符串,
# 并通过if判断对两个数字进行运算和结果输出
# (涉及到精准度问题,需要保留小数点后两位小数,使用round(x,2)方法,x为值,2为小数点后两位)
# num_1 = float(input("请输入第一个数字:"))
# num_2 = float(input("请输入第二个数字:"))
# operation_symbol = input("请输入(+、-、*、/)中的运算符号:")
#
# if operation_symbol == "+":
# print(num_1 + num_2)
# elif operation_symbol == "-":
# print(num_1 - num_2)
# elif operation_symbol == "*":
# print(num_1 * num_2)
# elif operation_symbol == "/":
# print(round((num_1 / num_2), 2))
# 3.结合以上条件,引用while循环,让其可以循环输入运算符号和计算结果,添加输入错误提示:"输入有误,无法识别,请重新操作",
# 输入"exit"退出系统功能(while、continue、break)
# num_1 = float(input("请输入第一个数字:"))
# num_2 = float(input("请输入第二个数字:"))
#
# while True:
# operation_symbol = input("请输入(+、-、*、/)中的运算符号:")
# if operation_symbol == "+":
# print(num_1 + num_2)
# elif operation_symbol == "-":
# print(num_1 - num_2)
# elif operation_symbol == "*":
# print(num_1 * num_2)
# elif operation_symbol == "/":
# print(round((num_1 / num_2), 2))
# elif operation_symbol == "exit":
# print("退出系统")
# break
# else:
# print("输入有误,无法识别,请重新操作")
# continue
# 4.一家商场在降价促销,如果购买金额50-100元(包含50和100元)之间,会给10%的折扣,如果购买金额大于100元会给20%的折扣,
# 编写一个程序,询问购买价格,再显示出折扣,(10%或20%,可以直接乘以0.1或者0.2)和最终价格
# amount = float(input("请输入购买的金额: "))
# if 50 <= amount <= 100:
# print("您当前购买的金额享受10%的折扣,折算完的金额为: {}元".format(amount - amount * 0.1))
# elif amount > 100:
# print("您当前购买的金额享受20%的折扣,折算完的金额为: {}元".format(amount - amount * 0.2))
# 5.输入一个年份,输出是否为闰年。
# 闰年条件:能被4整除但不能被100整除,或者能被400整除但年份都是闰年
# year_num = int(input("请输入年份:"))
# if year_num % 4 == 0 and year_num % 100 != 0 or year_num % 400 == 0:
# print("您输入的年份是闰年!")
# else:
# print("您输入的年份不是闰年!")
# 6.完成一个猜数字游戏
# 进入程序后
# 提示用户输入 要猜的数字
# 其他人输入时,提示数字大了,或者小了
# 猜到正确的数字为止,提示恭喜猜对了
# (选做1:可以控制每位玩家的猜数字次数,例如,一个人只能猜3次,3次猜错结束程序,显示正确的数字后,重新开始)
# (选做2: 猜数字的游戏中的数字尝试让系统生成,提示:random.randint(n,m) 可以让python在n-m之间生成一个随机数)
# be_guess_num = float(input("请输入要猜的数字为: "))
#
# while True:
# guess_num = float(input("请输入猜测的数字为: "))
# if guess_num > be_guess_num:
# print("数字太大!")
# elif guess_num < be_guess_num:
# print("数字太小!")
# else:
# print("恭喜你,猜对了!")
# break
# (选做1:可以控制每位玩家的猜数字次数,例如,一个人只能猜3次,3次猜错结束程序,显示正确的数字后,重新开始)
# be_guess_num = float(input("请输入要猜的数字为: "))
# num = 0
#
# while num < 4:
# num += 1
# guess_num = float(input("请输入猜测的数字为: "))
# if guess_num > be_guess_num:
# print("数字太大!")
# elif guess_num < be_guess_num:
# print("数字太小!")
# else:
# print("恭喜你,猜对了!")
# break
#
# if num == 3:
# print("次数已用尽,正确的数字为: {},游戏重新开始".format(be_guess_num))
# num = 0
# continue
# (选做2: 猜数字的游戏中的数字尝试让系统生成,提示:random.randint(n,m) 可以让python在n-m之间生成一个随机数)
# import random
#
# be_guess_num = random.randint(1, 100)
# num = 0
#
# while num < 4:
# num += 1
# guess_num = float(input("请输入猜测的数字为: "))
# if guess_num > be_guess_num:
# print("数字太大!")
# elif guess_num < be_guess_num:
# print("数字太小!")
# else:
# print("恭喜你,猜对了!")
# break
#
# if num == 3:
# print("次数已用尽,正确的数字为: {},游戏重新开始".format(be_guess_num))
# num = 0
# continue
# 7.【项目】结合今天所学的内容,对上节课的作业项目进行升级
# 模拟课堂上的project_duck,改编自己的书籍项目(包含while、break、if等知识点)
print("欢迎来到七夜老师的python书店")
book_name = None
book_author = None
book_num = None
book_price = None
print(book_price, book_author, book_num, book_name)
while True:
input_txt = input("请输入您要选择的操作\n1 - 录入书籍\n2 - 查询书籍\n3 - 退出")
if input_txt == "1":
book_name = input("请输入书籍的名称:")
book_author = input("请输入书籍的作者:")
book_num = input("请输入书籍的库存数量:")
book_price = input("请输入书籍的售卖价格:")
elif input_txt == "2":
print("书籍的名称: {}".format(book_name))
print("书籍的作者: {}".format(book_author))
print("书籍的库存数量: {}".format(book_num))
print("书籍的售卖价格: {}".format(book_price))
elif input_txt == "exit":
print("退出系统!")
break
数字为止,提示恭喜猜对了
# (选做:可以控制每位玩家的猜数字次数,例如,一个人只能猜3次,3次猜错结束程序,显示正确的数字后,重新开始)
# (选做: 猜数字的游戏中的数字尝试让系统生成,提示:random.randint(n,m) 可以让python在n-m之间生成一个随机数)
# 7.【项目】结合今天所学的内容,对上节课的作业项目进行升级
# 模拟课堂上的project_duck,改编自己的书籍项目(包含while、break、if等知识点)
"""
四、列表和字典的定义与操作
Python可视化网址:Python Tutor code visualizer: Visualize code in Python, JavaScript, C, C++, and Java
Project_Duck(烤鸭店例子):
需求:
烤鸭店利润计算器:计算这个烤鸭店每天的利润是多少?
要求:
a)要求提示页面友好
b)要求自己可以手动输入收入、成本、鸭子数量
(1)收入 - 成本 = 利润
# 第一个版本: print("欢迎使用烤鸭店利润计算器!")
price1 = input("请输入今天的收入金额为: ")
# 1000
price2 = input("请输入今天的成本金额为: ")
# 600
result = price1 - price2
# 问题:这种方式可行么?不行,input函数所接受的值是str类型
# 报错信息:unsupported operand type(s) for -: 'str' and 'str'
优化后的代码:
# 优化后的代码:
print("欢迎使用烤鸭店利润计算器!")
price1 = int(input("请输入今天的收入金额为: "))
# 1000
price2 = int(input("请输入今天的成本金额为: "))
# 600
result = price1 - price2
print(f"今天的纯收入是:{result}")
(2)(单个鸭子的售卖价格 - 成本价格) * 今天售卖的鸭子数量 = 今天烤鸭店的利润
print("欢迎使用烤鸭店利润计算器!")
price1 = int(input("请输入今天的收入金额为: "))
# 1000
price2 = int(input("请输入今天的成本金额为: "))
# 600
duck_num = int(input("请输入今天售卖的鸭子数量为: "))
result = (price1 - price2) * duck_num
print(f"今天的收入金额为: {price1}, 成本金额为: {price2}, 纯收入是:{result}")
(3)由于烤鸭店的利润太少了,想要新增一些商品类型[属性:商品的名称、价格、生产日期、生产地、保质期 ... ...]
错误示例:
p1 = "北京烤鸭" m1 = 80 p2 = "北京卷饼" m2 = 5 # ... ... 要新增很多的商品,那么这种写法可行么?一种商品可能存在5条属性,那么如果有100种商品,是不是存在100 * 5 = 500行代码? # 原因:维护性特别差,一般不这么做 -- 开发一时爽,维护火葬场
1.列表
列表的定义:
定义:一种将多个数据组合在一起的容器
标识符:[ ]
关键字:list
定义一个空列表
lst1 = []
定义一个有值的列表,每个元素之间用英文的逗号隔开
lst2 = [1, 2, 3, 4]
获取列表的类型:
lst2 = [1, 2, 3, 4] # 定义一个有值的列表,每个元素之间用英文的逗号隔开 print(type(lst2)) # <class 'list'>
列表的增删改查操作:
特征:有序、可变
有序:列表中的每个元素都是有索引(python中的索引,都是默认从 0 开始)

列表的取值语法:列表的变量名称[索引的值]
lst1 = [1, 2, 3, 4, 5] print(lst1[3]) # 4
获取列表的长度 -- len()
lst1 = [1, 2, 3, 4, 5] # 有几个元素,那么len长度就是多少 print(len(lst1))
列表可以倒叙输出 -- reverse()
lst1.reverse() # 先执行方法完成倒叙 print(lst1) # 然后再去查询 #错误写法 print(lst1.reverse()) #一边打印,一边倒叙的话,会打印为None(表示的是这个函数没有返回值)这个None在后面的函数会讲
小测验:
lst3 = [100, 3.14, True, "qiyelaoshi", [1, 2, 3, 4]] # 问题1:获取 "qiyelaoshi" 这个值 print(lst3[3]) # 问题2:请问lst3的len长度为多少? print(len(lst3)) # 问题3:获取 3 这个值? print(lst3[4]) # 这个元素还是list类型的值 #想要获取到嵌套的数据,先找到最外面的一层 print(lst3[4][2]) # 把lst3[4]视为一个整体的list,然后使用list取值的方式进行操作 # 问题4:lst3的长度为? lst3 = [100, 3.14, True, "qiyelaoshi", [1, 2, 3, 4], [1, 2, 3, 4, [1, 2, 3, 4], [1, 2, 3, 4]]] # 快捷的查看方式:数括号,括号是一一对应的,从最外层开始数 print(len(lst3)) #6


列表的增加 -- append()
会把添加的值,默认加在末尾,一次只能添加一个元素
lst1 = [1, 2] lst1.append("qiyelaoshi")
print(lst1)
# 错误示例:
lst1.append("qiyelaoshi", "xiaominglaoshi")
# list.append() takes exactly one argument (2 given)
列表的添加 -- insert()
通过索引来进行添加,添加的位置就是索引的位置,原有位置元素下标会依次加一?
lst1 = [1, 2] #按照下标完成添加,插入数据前面的下标不管,后面的数据下标依次递增+1 lst1.insert(0, "qiyelaoshi") print(lst1)
合并列表 -- extend()
把元素一个个的放入到新的列表中
lst1 = [1, 2]
lst2 = [2, 3, 4, 5]
# print(lst1 + lst2)
# 不建议在企业中,写法太低级,看起来像是加法运算
lst1.extend(lst2)
print(lst1)
# 把str类型的数据,合并到列表中
lst1.extend("七夜老师")
# str类型也是可以视为列表
print(lst1)
# [1, 2, '七', '夜', '老', '师']
#错误示例,数字类型不可迭代
lst1.extend(100)
print(lst1)
列表的删除 -- remove()
直接删除具体的值,如果存在多个的话,默认删除最前的那个
lst1 = [1, 2] lst2 = [2, 3, 4, 5, 2] lst1.remove(2) print(lst1) # 问题:通过remove删除lst2中的值2 ,那么会删除前面的还是后面的 lst2.remove(2) print(lst2)
列表的删除 -- pop()
不带下标,默认删除最后一个,带下标删除具体的值
lst1 = [1, 2] lst2 = [2, 3, 4, 5, 2] # lst1.pop() # print(lst1) lst2.pop(3) print(lst2)
列表的删除--del
请删除列表中的第2至第4个元素 del li[1:4]
列表的修改
-- 列表的变量名称[下标] = 新值
lst3 = [100, 3.14, True, "qiyelaoshi", [1, 2, 3, 4]] # 问题1:把 True 改为False? # lst3[2] = False # print(lst3) # [100, 3.14, False, 'qiyelaoshi', [1, 2, 3, 4]] # 问题2:把 3 改为 10 ? lst3[4][2] = 10 print(lst3) # [100, 3.14, True, 'qiyelaoshi', [1, 2, 10, 4]]
烤鸭店项目的升级:
project_duck_3.0
print("欢迎使用烤鸭店利润计算器!") price1 = int(input("请输入今天的收入金额为: ")) # 1000 price2 = int(input("请输入今天的成本金额为: ")) # 600 duck_num = int(input("请输入今天售卖的鸭子数量为: ")) result = (price1 - price2) * duck_num print(f"今天的收入金额为: {price1}, 成本金额为: {price2}, 纯收入是:{result}")
通过列表对烤鸭店进行升级,提高代码的可维护性
project_duck_3.1
print("欢迎使用七夜老师的烤鸭店利润计算器!")
projects = {} #定义一个最外层的的数据,用于保存
while True: # 让系统可以循环使用,不用每次都手动执行
# 提供一个可选择功能的菜单
#转义字符,键盘上有部分的键,不能在代码中显示
#\n表示换行的意思
#如果说不希望字符串自动转义---在引号的前面加一个r,比如r"请输入对应的数字进行功能选择:\n1.录入商品的功能\n2.查询商品的功能\n3.退出系统的功能\n"
oper_type = input("请输入对应的数字进行功能选择:\n1.录入商品的功能\n2.查询商品的功能\n3.退出系统的功能\n")
if oper_type == "1":
# 1.录入商品的功能
pro_list = [] # 定义一个空列表
load_name = input("请输入你的商品名:")
pro_list.append(load_name)
price = input("请输入你的成本价:")
pro_list.append(price)
s_value = input("请输入你的产地:")
pro_list.append(s_value)
data_time = input("请输入你的生产日期:")
pro_list.append(data_time)
# 问题:怎么把pro_list的值,加到projects里面去?
projects[load_name]=pro_list
elif oper_type == "2":
# 2.查询商品的功能
print(projects)
po_name=input("请输入你要查询的商品名称:")
print(f"您要查询的商品信息:{projects[po_name]}")
elif oper_type == "3":
# 3.退出系统的功能
break # 直接跳出整个循环
else:
print("系统无法识别你的输入,请重新选择!")
continue # 跳出当前循环,重新判断条件
2. 字典
字典的定义:
定义:具有键值对映射关系的一组无序的数据组合
键值对映射: key : value -- key是键名,value是这个键所对应的具体值,通过key来查询
关键字:dict
标识符:{}
无序:没有索引 一个字典里的key不会重复
key:是唯一的,并且不能修改的数据,通常我们用str类型
value: 可以是任何类型的数据,可以修改
定义一个空字典
dic1 = {}
定义一个有值的字典
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
字典的查询 -- 字典的变量名称["key"]`
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
print(dic2["students_name"]) # ['二师兄', '千寻', '听风、', '自由']
小测验:
问题:查询 听风、这个值?
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
print(dic2["students_name"][2]) # 听风、
字典的增删改操作:
字典的新增
字典的变量名称["字典中不存在的key"] = 新值---向字典中添加一组键值对
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2['addr'] = "湖南长沙"
print(dic2)
# {'name': '七夜老师', 'age': 18, 'cls': 234, 'students_name': ['二师兄', '千寻', '听风、', '自由'], 'addr': '湖南长沙'}
字典的修改
-- 字典的变量名称["字典中存在的key"] = 新值---把原有字典的value换成新的
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2['age'] = 20
print(dic2)
提问:把 自由 的值,改为 小玉 ?
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2["students_name"][3] = "小玉"
print(dic2)
字典的删除 -- pop()
不能为空,需要传入删除的key
错误的示例:
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2.pop() # pop expected at least 1 argument, got 0

正确的示例:
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2.pop("age")
print(dic2) # {'name': '七夜老师', 'cls': 234, 'students_name': ['二师兄', '千寻', '听风、', '自由']}
字典的删除 -- popitem()
从后往前删出
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2.popitem()
print(dic2) # {'name': '七夜老师', 'age': 18, 'cls': 234}
问题:当dict中所有的key都被删除了,还剩下什么?
dic2 = {
"name": "七夜老师",
"age": 18,
"cls": 234,
"students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2.popitem()
dic2.popitem()
dic2.popitem()
dic2.popitem()
print(dic2) # {}
字典的清空 -- clear()
dic2 = { "name": "七夜老师", "age": 18, "cls": 234, "students_name": ["二师兄", "千寻", "听风、", "自由"] }
dic2.clear()
print(dic2) # {}
转义字符:键盘上有部分键,不能在代码里显示, 用英文去代替特殊键位

五、for循环和切片
循环
特征:遍历、循环
遍历:复杂的数据结构中,将里面的元素一个个的获取出来
循环:自带循环的效果,循环的次数由可遍历数据的长度来决定
语言结构:
for 变量名 in 可遍历的数据: # 变量名:自定义的变量名(可以获取到每次循环的元素); 可遍历的数据包含:列表、字符串... ...
循环体的代码:每循环一次,执行一遍循环代码
通过for循环直接读取
lst1 = [1, "七夜老老师", 3, "a", "b", 6]
for i in lst1:
print(i)
小测验:
# 此时,打印的i的值为多少?
j = 0 # 初始值
for i in lst1:
if j % 2 == 0: # j取值的范围为多少:0,2,4
print(i)
j += 1 # j每次循环都递增1
# 答案:1, 3, "b"
迭代器:range() 用于生成一个整数的序列,提供一个数字,自动生成一个序列列表(规则:左闭右开) -- 可迭代的对象
r = range(10) print(list(r)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] r1 = range(8) print(list(r1)) # [0, 1, 2, 3, 4, 5, 6, 7]
range()可以设置初始值,如过不设置,默认为0,如果设置了,只能够取到初始值到结束值之间的内容 -- 左闭右开
示例:
r2 = range(1, 10) print(list(r2)) # [1-9] r3 = range(8, 9) print(list(r3)) # [8]
range()结合for循环进行使用:
for i in range(10): # [0-9]
print(i)
小测验:
# 问题1:for循环不能够遍历非可迭代的数据,比如:int类型
# for i in 10: # 'int' object is not iterable
# print(i)
# 问题2:for循环可以遍历str类型?str类型是可以当做列表
for i in "七夜老师":
print(i)
# 问题3:如果range()的开始值和结束值为同一个的话,能否取到值?
r4 = range(8, 8)
print(list(r4))
# [] 无法同时满足两个条件,则取不到值
双重for循环
for循环的嵌套
示例:
# k = 0 # 初始值
#
# for i in range(1, 10):
# [1-9]
#
# for j in range(1, 10):
# k += 1
# 每循环一次,k都会递增1 #
# print(f"k此时的值为:{k}")
# 当第一层for循环,循环1次的时候,里面这个for循环,循环几次?
# i每循环1次,都会让j循环9次,i最终会循环9次,就会导致双重for循环的最终循环次数:9 * 9 = 81
小测验:
笔试题:打印九九乘法表
1 * 1 = 1
1 * 2 = 2, 2 * 2 = 4
1 * 3 = 3, 2 * 3 = 6, 3 * 3 = 9
...
1 * 9 = 9, 2 * 9 = 18, 3 * 9 = 27
...
正确的写法和思路:
# print("{} * {} = {}".format(1, 2, 1 * 2))
# 定义了两个变量,一个是i,一个是j,总共的循环次数为81次
for i in range(1, 10): # [1-9]
for j in range(1, i+1): # [1 - 9]
print("{} * {} = {}".format(j, i, i * j), end=' ') # 防止换行
# 问题:当循环到第几次的时候,要求换行?
print() # 这个print放在哪个循环里面?j?i? -- i
# 当 i = 1 , 此时 j = [1-9],j循环打印的时候,有没有换行? -- j是不进行换行
# 核心点1:
# 谁负责纵向的循环,谁负责横向的循环?
# j:横向,i:纵向
# 核心点2:
# 出现了多余的数据,应该修改谁的取值范围? -- j # i = 1, j循环9次,实际的需求:1次
# i = 2,j循环9次,实际的需求:2次
# i = 3,j循环9次,实际的需求:3次
# i = 4,j循环9次,实际的需求:4次
# i = 5,j循环9次,实际的需求:5次
# i = 6,j循环9次,实际的需求:6次
# 核心点3:
# 怎么修改j的取值
# i和j的初始取值都是一样的,那么j的取值范围range()的开始值不改变
# i = 1 的时候,j的取值range(1, 2)才可以取到值1
# i = 2 的时候,j的取值range(1, 3)才可以取到值1, 2 # i每次递增,那么j的range(1, i+1)
查看源码**:Ctrl + 鼠标左键 点击你要查看的函数/方法内容**
print的源码:
因为print里面有\n,那么就表示print方法执行的时候,会自动换行
切片操作
列表的切片
列表的切片:分割一个列表,只提取其中某一个片段出来
语法规则:列表的变量名称[start:end:step]
start:开始值,从哪个地方开始
end:结束值,从哪里结束
step:步长,每隔几个元素获取一次值,默认值:1,可以省略,但是不能为0,否则就会报错
示例:
lst1 = [100, 3.14, True, "Huace", [1, 2, 3, 4]] # 根据下标取值 # print(lst1[1]) # 切片取值: # print(lst1[0:2]) # start:end,[100, 3.14] # print(lst1[1:2]) # 结果:[3.14] # print(lst1[1:4]) # [3.14, True, 'Huace'] # 问题:获取 True, "Huace" 的值,怎么写? # print(lst1[2:4]) # print(lst1[0:-1]) # 行不行?可以,[100, 3.14, True, 'Huace'] # print(lst1[:3]) # start 省略 # print(lst1[1:]) # end 省略 # print(lst1[0::2]) # 每隔几个元素,取一次值 print(lst1[0::0]) # slice step cannot be zero
切片的赋值方式,切记不要变量直接赋值变量
lst2 = [1, 2, 3, 4] lst3 = lst2 # 变量赋值变量的操作 # print(lst3) # print(lst2) # 隐患问题存在,如果给lst3中添加一个元素,那么lst2的元素是否会发生变化? -- 相等,安全性问题 lst3.append(5) print(lst3) print(lst2)

统计数据中元素的个数,count(元素具体值) -- 判断这个元素在我们列表中有几个
一个萝卜一个坑,判断的是最外面的数据中,有几个目标元素
lst1 = [100, 3.14, True, "Huace", [1, 2, 3, 4, True, True], [True, True]] print(lst1.count(True))
字符串的切片
str类型可以当做列表
语法规则:列表的变量名称[start:end:step]
start:开始值,从哪个地方开始
end:结束值,从哪里结束
step:步长,每隔几个元素获取一次值,默认值:1,可以省略,但是不能为0,否则就会报错
示例:
str1 = "hello python" # res = str1[0] # print(res) # res1 = str1[5] # 空格也是一个元素 # print(res1) # 负数取值,倒过来取值,取第几个 # res2 = str1[-1] # print(res2) # for i in str1: # print(i) # str类型的切片 # res3 = str1[0:3:2] # print(res3)
Project_Duck(烤鸭店项目)
project_duck_4.1:
print("欢迎使用七夜老师的烤鸭店利润计算器!")
projects = {}
while True: # 让系统可以循环使用,不用每次都手动执行
# 提供一个可选择功能的菜单
oper_type = input("请输入对应的数字进行功能选择:\n1.录入商品的功能\n2.查询商品的功能\n3.退出系统的功能\n")
if oper_type == "1":
# 1.录入商品的功能
pro_list = [] # 定义一个空列表
# 1) 把input里面的str数据,放在一个列表中
load_txt = ['请输入你的商品名:', "请输入你的成本价:", "请输入你的产地:", "请输入你的生产日期:", "请输入商品的属性a: ", "请输入商品的属性b: "]
# 2) 把列表中的str数据,通过for循环,依次放在input中
# for i in load_txt:
# input(i)
# 3) 在通过变量的重定义,重新赋值定义一个变量,用来接收input每次循环时所接收的值
# for i in load_txt:
# load_name = input(i) # 4) 把接收的值,依次添加到pro_list列表中
for i in load_txt:
load_name = input(i)
pro_list.append(load_name) # 问题:怎么把pro_list的值,加到projects里面去?
# projects.append(pro_list)
projects[pro_list[0]] = pro_list
# key的值应该用哪个?给商品名称,value给整个商品的属性列表
elif oper_type == "2":
# 2.查询商品的功能
# 如果想自己输入查询的商品名称进行查询 -- 根据key的名字查询对应的value
print(projects)
# 用户自己输入查询的商品名称
po_name = input("请输入您要查询的商品名称:")
print(f"您查询到的商品信息为: {projects[po_name]}")
elif oper_type == "3": # 3.退出系统的功能
break # 直接跳出整个循环
else:
print("系统无法识别你的输入,请重新选择!")
continue # 跳出当前循环,重新判断条件
回退缩进:shift + tab
六、 元组、集合和函数的定义与返回值
元祖
元组的定义
元组的数据结构跟列表相似
特征:有序、不可变
-
有序:有(索引/下标/index) 正序、反序
-
标识符: ( ) 里面的元素是用英文格式的逗号分割开来
-
关键字:tuple
面试中常问的问题:列表和元组有什么区别?
元组是不可变的:程序在运行的时候,无法对其进行改变 -- 没有提供关键字、方法去操作它,没有增删改的操作
问题:既然无法对其进行变化,那么为什么要有元组的存在?
安全性考虑 -- 国内的省份(省、市) 变量,常量
但凡是可以进行操作的数据,都存在安全隐患
示例:
tp = () # 定义一个空元组 print(type(tp)) # <class 'tuple'> tp1 = (1, 2, 3, 4, 5) # 定义一个有值的元组 print(tp1)
元组的基本查询,根据下标
tp1 = (1, 2, 3, 4, 5) print(tp1[0])
元组为什么不可以进行变化(不是指的手动修改代码)
列表修改示例:
lst1 = [1, 2, 3, 4]
num = 0 # 初始值
while True:
if num > 5:
lst1.append(5)
time.sleep(2) # 强制等待的时间,单位:秒
print(f"此时lst1的实际长度为: {len(lst1)}")
num += 1 # 每循环一次叠加1
# 问:当数据为lst1的时候,发生长度变化之前,是循环了几次? 6次
元组修改示例:
import time
lst1 = [1, 2, 3, 4] # 列表是可以提供变化的
tp1 = (1, 2, 3, 4)
num = 0 # 初始值
while True:
if num > 5:
tp1.append(5) # 报错:'tuple' object has no attribute 'append'
time.sleep(2) # 强制等待的时间,单位:秒
print(f"此时lst1的实际长度为: {len(tp1)}")
num += 1 # 每循环一次叠加1 # 问题2:既然列表是可以在程序执行之间进行操作,那么换成元组行不行?
问题1:res是由tp1 和 tp2 拼接在一起的,还是额外生成的? -- 额外生成的一个新元组
tp1 = (1, 2, 3, 4) tp2 = (100, 3.14) res = tp1 + tp2 print(res) print(type(res))

问题2:元组乘以int类型的数字的res1是打印两次tp1,还是额外生成一个新的元组?
tp1 = (1, 2, 3, 4) tp2 = (100, 3.14) res1 = tp1 * 2 print(res1) print(type(res1))

小测验:如果给你一个元组,需要修改这个里面的数据,怎么做? -- 先转换成列表,修改数据,然后在转化成元组
tp1 = (1, 2, 3, 4)
# 获取修改之前的内存地址
print(f"修改之前的内存地址: {id(tp1)}")
# 1.先转换成列表
lst1 = list(tp1)
# print(lst1)
# print(type(lst1))
# 2.修改数据
lst1.append(5)
# print(lst1)
# print(type(lst1))
# 3.然后在转化成元组
tp1 = tuple(lst1)
# 变量的重定义 -- 对变量进行重新赋值
# print(tp1)
# print(type(tp1))
# 获取修改之后的内存地址
print(f"修改之后的内存地址: {id(tp1)}")
# 问题:修改之前的tp1的内存地址和修改之后的一样么? 不一样,是一个新的元组,只是引用的变量名称是一样的,但是存放的内存地址不一样
问题:谁是元祖类型? -- 每个元素都是需要用逗号分隔开来的
num1 = (1,) num2 = (1) print(type(num1)) # <class 'tuple'> print(type(num2)) # <class 'int'>
集合
集合的定义
定义:由不同的元素组成的一个数据结构,无序排列的
标识符:{ }
关键字:set
特征:无序,元素不能重复,集合和集合之间可以做运算
单个元素的集合定义
set2 = {1,}
print(type(set2))
无序排列 -- 存放在内存地址之前是无序的
set1 = {"欢迎", "来到", "七夜", "老师", "的", "课堂", "!"}
print(type(set1)) # <class 'set'>
print(f"猜一猜,set1集合中的第一个值是? {set1}")
print(f"第二次打印无序的集合:{set1}")
print(f"第三次打印无序的集合:{set1}")
# 随机的结果:
<class 'set'>
猜一猜,set1集合中的第一个值是? {'欢迎', '来到', '老师', '课堂', '的', '!', '七夜'}
第二次打印无序的集合:{'欢迎', '来到', '老师', '课堂', '的', '!', '七夜'}
第三次打印无序的集合:{'欢迎', '来到', '老师', '课堂', '的', '!', '七夜'}
集合里面的元素不能重复 -- 自动去重
set2 = {"七夜老师", "三丰老师", "小明老师", "长风老师", "哈米老师", "七夜老师", "三丰老师"}
print(set2) # {'三丰老师', '哈米老师', '小明老师', '长风老师', '七夜老师'}
集合的操作
进行强制转换
set1 = {"欢迎", "来到", "七夜", "老师", "的", "课堂", "!"}
lst1 = list(set1)
print(type(lst1))
print(f"lst1中的第一个值:{lst1[0]}") # 不确定、随机的
问题:如果转换完成后,连续打印,第一次的值和后面N次的值,是一样的么?
答:一样的,原理:存放内存地址之前,是随机的,但是一旦存放了,后续的内容都是固定的
set1 = {"欢迎", "来到", "七夜", "老师", "的", "课堂", "!"}
lst1 = list(set1)
print(type(lst1))
print(f"lst1中的第一个值:{lst1[0]}") # 不确定、随机的
print(f"lst1第二次打印第一个值:{lst1[0]}")
print(f"lst1第三次打印第一个值:{lst1[0]}")
print(f"lst1第四次打印第一个值:{lst1[0]}")
集合的添加 -- add()
set1.add("2024")
# print(set1)
集合的删除 -- pop(随机删除,因为没有下标)、remove(删除指定的值)
# set1.pop() # 随机删除,因为没有下标
# print(set1)
# set1.remove("七夜") # 删除指定的值,如果删除不存在的值,会报错
# set1.remove("七夜")
# print(set1)
set1.discard("老师") # 提前准备好,想删除的值,删除多次,都不会报错
set1.discard("老师")
print(set1)
集合的运算
运算的方式:交集、并集、差集、交叉补集
交集:获取两个集合之间相同的部分 -- intersection
set1 = {"七夜老师", "小明老师"}
set2 = {"七夜老师", "长风老师"}
print(f"获取两个集合之间相同的部分: {set1.intersection(set2)}")
# 获取两个集合之间相同的部分: {'七夜老师'}
并集:合并两个集合,自动去重 -- union
set1 = {"七夜老师", "小明老师"}
set2 = {"七夜老师", "长风老师"}
print(f"合并两个集合,自动去重: {set1.union(set2)}")
差集:获取集合中,另一个集合没有的内容 -- difference
set3 = {"七夜老师", "高", "富", "帅"}
set4 = {"小明老师", "高", "矬", "富"}
print(f"获取对方有,但是自己没有的元素: {set3.difference(set4)}")
交叉补集:剔除公有的内容,留下双方独有的内容
set3 = {"七夜老师", "高", "富", "帅"}
set4 = {"小明老师", "矮", "矬", "穷"}
print(f"剔除公有的内容,留下双方独有的内容: {set3.symmetric_difference(set4)}")
函数
函数的定义
定义:将一段公式/逻辑代码定义在一个特定的标题(函数名称)下,通过一块,或者一行代码来执行固定好的逻辑,而这些代码只有函数被调动的时候才会执行
通俗点:封装一些代码
核心点:函数的定义、函数的调用
函数的定义:封装好的代码,只有在调用的时候,才会执行 -- 定义函数的时候,不会执行函数内部的代码
函数的调用:语法:函数的名称() -- 调用函数,执行函数内部的代码
函数定义
语法规则:
def 自定义的函数名称(): 封装的代码 ... ...
定义函数,如果不进行调用,是不会运行函数内部的代码(注意:自定义的函数名称,不要和python关键字、已存在的函数名称重复)
# 示例:线性脚本
# m = 1
# n = 2
# s = m + n
# print(f"m + n 的结果:{s}")
# 封装之后,不再是简单的线性脚本
def add1(): # 函数的名称: add1
# 需要封装的代码
m = 1
n = 2
s = m + n
print(f"m + n 的结果:{s}")
调用函数 -- 函数的名称() 表示调用函数,也就是执行函数的内部代码
def add1(): # 函数的名称: add1
# 需要封装的代码
m = 1
n = 2
s = m + n
print(f"m + n 的结果:{s}")
# 调用函数 -- 函数的名称() 表示调用函数,也就是执行函数的内部代码
add1()
函数的参数
定义函数的时候,可以在小括号里面定义一些参数
定义的参数,可以不给值,然后在调用函数的位置,进行传参
def demo1(name, age, addr):
print(f"""
=====demo1函数里面的参数=====
name: {name}
age: {age}
addr: {addr}
""")
位置参数:按照固定的位置进行传参
def demo1(name, age, addr):
print(f"""
=====demo1函数里面的参数=====
name: {name}
age: {age}
addr: {addr}
""")
demo1("七夜老师", 18, "湖南长沙")
指定参数:指定固定的参数进行传参
def demo1(name, age, addr):
print(f"""
=====demo1函数里面的参数=====
name: {name}
age: {age}
addr: {addr}
""")
demo1(age=18, name="七夜老师", addr="湖南长沙")
默认参数:定义函数的时候,可以设置参数的默认值 -- print函数里面的end='\n'
# def demo2(name="小明老师", age=88, addr=None):
# print(f"""
# =====demo1函数里面的参数=====
# name: {name}
# age: {age}
# addr: {addr}
# """)
#
#
# demo2(addr="湖南长沙", name="七夜老师")
问:默认参数是要么都传,要么就都不传吗?
答:定义函数的时候,如果给部分参数设置了默认值,那么非默认参数也要遵循默认参数的规则,否则得把非默认参数写在默认参数前面



不定长传参:单个*号 和 两个*号
单个*号的参数:args是默认的名称,可以随意修改 -- 元组类型
# def demo3(*args):
# print(f"获取到的值:{args}")
# print(f"获取值的类型: {type(args)}")
# print(args[0])
#
#
# demo3(1, 2, 3, 4, 5)
两个*号:kwargs是默认的名称,可以随意修改 -- 字典类型
# def demo4(**kwargs):
# print(f"获取到的值:{kwargs}")
# print(f"获取值的类型: {type(kwargs)}")
#
#
# demo4(name="七夜老师", age=18, addr="湖南长沙")
函数的返回值
注意事项:
1.函数的内部可以写return返回值,或者不写
2.如果不写return,也可以执行,不会报错,但是接收到的值,还是 None
3.如果写了,可以把需要传递的值,传递给调用函数的地方,通过两种方式获取(print、变量)
4.写了return但是没有传值的情况下,获取到的值是 None
5.如果有return返回值的情况下,可以通过两种方式获取
# def add1(): # 函数的名称: add1
# # 需要封装的代码
# m = 1
# n = 2
# s = m + n
# print(f"m + n 的结果:{s}")
#
#
# add1()
# 想获取s的值,然后进行 + 100的操作?
# print(s + 100) # 函数的作用域问题 -- 后面的课程会讲,暂时不讲
# def add2():
# m = 1
# n = 2
# s = m + n
# # 不直接写print,因为无法传递数据
# # 通过函数的返回关键字return,把数据传递给调用函数的地方
# return s
# add2()
# 问题:此时调用函数,会不会打印s的值? -- 不会
# 因为:没有对获取到的s值,进行打印操作
# 方式一:直接通过print打印获取到函数返回值
# print(f"获取到函数内部的s:{add2()}")
# 方式二:通过变量接收函数的返回值,然后进行后续的操作
# res = add2()
# print(f"res + 100的值:{res + 100}")
# 写了return但是没有传值的情况下,获取到的值是 None
# def add3():
# m = 1
# n = 2
# s = m + n
# return
# 如果不写return,也可以执行,不会报错,但是接收到的值,还是 None
# def add4():
# m = 1
# n = 2
# s = m + n
#
#
# # 方式一:
# print(add4())
#
# # 方式二:
# res = add4()
# print(res)
# lst1 = [1, 2, 3]
# print(lst1.extend("七夜"))
课后作业
遇到的问题
1、pycharm中输入代码后会出现闪动的黑白方块
在键盘中点击一次“insert”键则会自动消失
2.获取两个数的最大值
max(num1,num2)
3.函数内部的变量需要定义后使用 (suum=0)
def sum(*args):
suum=0
for i in args:
suum = suum +i
return suum
4.return不打印返回值,print会打印返回值
5.""" """,可以是注释也可以是多行字符串输出
七、函数相关知识
函数的注释与嵌套
函数的注释
函数的注释与普通注释的区别:用来说明当前函数的参数含义
param 参数名: 参数的注释信息
return: 函数的返回值
def fun1(name):
"""
:param name: 参数的注释信息
:return: 函数的返回值
"""
print("fun1函数") # 查看源码的快捷键:Ctrl + 左键 点击要查看的函数
def fun2(name, age, addr, sal):
"""
:param name: 请输入姓名
:param age: 请输入年龄
:param addr: 请输入地址
:param sal: 请输入薪资
:return: 函数执行后的返回信息
"""
print("fun2函数")
# fun1()
# fun2()
# lst1 = [1, 2]
# lst1.append()
示例二:
def login(user, password):
"""
:param user: 请输入登录的用户名
:param password: 请输入登录的密码
:return: 返回账号信息校验的结果:True/False
"""
if user == 'admin' and password == '123456':
return True
# print(login(user='admin', password='123456'))
# login()
# 打印函数的注释
print(login.__doc__)
print(print.__doc__)
函数的嵌套
一个函数的内部调用另一个函数
# def fun1():
# print("欢迎来到七夜老师的课堂!")
# fun2() # 陷入死循环的情况
#
#
# def fun2():
# print("VIP 234 班级的直播课!")
# fun1() # 调用fun1函数
#
#
# # 问题:想在调用fun2函数的同时,去调用fun1函数?
# fun2() # 调用fun2函数
一个函数内部嵌套另一个函数
def fun3():
print("欢迎来到七夜老师的课堂!")
def fun4():
print("VIP 234 班级的直播课!")
fun4()
# 问题1:运行fun3函数,会打印几句话?
# fun3()
# 如果不调用函数,是不会去运行函数的内部代码的!!!
# 问题2:能不能在最外层,调用fun4函数?
# fun4() # name 'fun4' is not defined
# 在函数的内部定义的函数,不能直接在最外层调用 -- 函数的作用域
# 问题3:那么怎么去调用fun4函数呢?
# 应该在fun4函数定义的同级
fun3()
python中的内置函数
作用域函数
作用域:定义的变量和函数在哪个范围内可用
文件和文件之间定义的东西,一般不能直接用
函数内定义的东西,不能在文件中直接使用,哪怕同一个文件也不行
类中定义的东西,只在类的内部生效,不能在文件中直接使用
变量:
全局变量 -- 在当前文件内定义的变量,可以在文件任何地方使用
局部变量 -- 在有效范围内可以调用,出了范围就不能用了
类声明的变量也是一样,类的概念后面再说(8节课)
局部变量在定义的时候可以直接声明为全局变量
# def fun1():
# a = 10
# 问题1:能不能再最外层,直接引用变量a?
# print(a) # name 'a' is not defined
# 不可以直接引用
# 全局变量
# a = 10 # 定义了一个全局变量a
#
#
# def fun2():
# b = 5 # 局部变量
# # print(a)
# print(b)
#
#
# # print(a)
# fun2()
# 问题2:b变量的作用域是fun2函数的内部
# print(b)
# 问题3:如果想把函数内部的局部变量的值,传递到函数的外部进行使用?
# def fun3():
# s = 20
# return s # 返回函数的数据、结果给到调用函数的位置
#
#
# s = fun3()
# s1 = s + 100
# print(s1)
# 问题4:如果想传递多个的函数内部的参数,怎么办?
# def fun4(name, age, addr, sal):
# return name, age, addr, sal
#
#
# name, age, addr, sal = fun4(name="七夜老师", age=18, addr="湖南长沙", sal=500)
# print(f"""
# =====自我介绍=====
# name: {name}
# age: {age}
# addr: {addr}
# sal: {sal}
# """)
局部变量定义成全局变量
通过global关键字,先声明变量,然后再去赋值
# def fun6(): # b = 5 # 未声明 # global c # 已声明 # c = 6 # # # fun6() # # 哪怕是通过global关键字,转化成全局变量,也不可以直接使用,必须使声明的代码(所在的函数)被执行 (注意) # print(c)
在while里面,定义的全局变量,可以进行变量的重定义
e = 10
while True:
e = 5
break
print(e)如果在循环内部重新定义这个变量,那么这个全局变量的值就被改变了
# 问题:e最后打印的值?
a = 1
a = 2
print(a)
数学函数
abs() 绝对值
divmod() 返回商和余数
round() 四舍五入(银行家算法)
pow() 次方
sum() 求和
min() 最小值
max() 最大值
abs() 绝对值
print(abs(-1)) # 1
divmod() 返回商和余数
# x = int(input("请输入一个整型:"))
# a, b = divmod(x, 2)
# print(f"商:{a}")
# print(f"余:{b}")
round() 四舍五入(银行家算法)
奇数:四舍五入,偶数:直接舍去(这个规则,只在0.5区间生效)
# print(round(1.5)) # 2 # print(round(3.5)) # 4 # print(round(5.5)) # 6 # # print(round(2.5)) # 2 # print(round(4.5)) # 4 # print(round(6.5)) # 6 # print(round(4.9)) # print(round(4.6)) # print(round(4.51))
pow() 次方
print(pow(10, 2))
sum() 求和
lst1 = [1, 2, 3, 4, 5, 6, 7] print(sum(lst1))
min() 最小值
print(min(lst1))
匿名函数
匿名函数的定义
匿名函数:就是没有名字的函数
python lambda表达式实现匿名函数
语法规则:
lambda 参数: 逻辑
匿名函数里面的参数名称,是自定义
结果就是返回表达式的结果
示例一:
import math # 导入
# pai = math.pi
# print(f"圆周率π: {pai}")
#
# # 圆的面积计算公式: s = π * r²
# r = 5 # 圆的半径
# s = math.pi * pow(r, 2)
# print(f"圆的面积: {s}")
# 方式一:普通的函数定义
def s_area(r):
"""
:param r: 圆的半径
:return: 返回圆的面积
"""
s = math.pi * pow(r, 2)
return s
print(f"当r的值为5的时候,圆的面积: {s_area(r=5)}")
# 方式二:匿名函数的定义
res = lambda r: math.pi * pow(r, 2)
print(f"当r的值为5的时候,圆的面积: {res(r=5)}")
匿名函数的使用
lst1 = [10, 20, 30, 40]
res1 = lambda a: min(a)
print(f"获取lst1列表中的最小值:{res1(a=lst1)}")
装饰器之函数传递
函数的传递
python中可以把函数当变量传递
所以这种情况下,可以直接执行被传入的函数
主题:函数的引用 和 调用
示例一:
# def fun1():
# print("欢迎来到七夜老师的课堂!")
# 函数的调用 -- 函数的名称(),就会执行函数的内部代码
# fun1()
# 函数的引用(所在的内存地址) -- 函数的名称,没有小括号
# print(fun1)
# <function fun1 at 0x7fbb180c8160>, function代表是一个函数、fun1表示函数的名称、at 0x7fbb180c8160表示函数所在的内存地址
# 问题:函数的调用,与函数的引用之间有什么区别?
# 函数的调用有小括号,函数的引用没有小括号
示例二:
def fun1():
print("欢迎来到七夜老师的课堂!")
def fun2(fun_name): # 参数的名称可以自定义
"""
:param fun_name: 传入函数的引用/本体
:return: 调用传入的这个函数
"""
print("这里是VIP 234 班级的直播课堂!")
print(f"此时fun_name获取的值:{fun_name}") # fun1函数的引用 -- 引用与调用之间的区别:有没有小括号
fun_name() # 请问:这是在调用哪个函数? -- 调用fun1函数
# 通过函数的引用,来完成,调用fun2函数的时候,去调用fun1函数
fun2(fun_name=fun1) # 把fun1函数,当做变量进行传值
调用
运行这个函数的内部代码
引用
提供这个函数所在的内存地址,然后加上小括号,就可以完成对这个函数的调用
口诀:有小括号叫调用,没有小括号叫引用
在引用函数的时候,不会因为没有传参,而报错
但是在调用函数的时候,会因为没有传参,而报错
def login(username, password):
print(f"""
===用户信息===
username: {username}
password: {password}
""")
def fun1(fun_name, value1, value2):
print("fun1函数")
fun_name(value1, value2)
fun1(fun_name=login, value1="admin", value2="123456")
八、装饰器、模块和文件操作
装饰器的详解
日志
程序运行的时候的记录 -- 日志
在实际工作中,python这样的东西,是放在服务器(linux)上运行的
日志其实就是记录下来当前程序的运行,协助我们定位问题
确定问题的方式(通过日志、报错信息去溯源)
import logging # 日志模块
日志模块,会有日志的级别定义
常见的日志级别:
warning:警告---warning和error
error:报错---error
debug:调试---都有
info:正常---没有debug
# 级别是自己设置:我们可以通过自定义级别去确定什么东西该被记录,什么东西不被记录
# 设置的级别,会打印自己以及比自己小的级别信息!!!
# DEBUG > INFO > WARNING > ERROR
logging.basicConfig(level=logging.DEBUG)
日志打印
# logging.info("自定义的info级别的输出内容")
# logging.debug("自定义的info级别的输出内容")
# logging.warning("自定义的info级别的输出内容")
# logging.error("自定义的info级别的输出内容")
日志输出和print打印有一些区别:
# 1.颜色不一样
# 2.语法不一样
# 3.日志打印的时候,会带有用户信息
注意事项:控制台里面的打印,有可能是日志在前,也有可能是print在前(日志和print打印的输出级别没有先后顺序 -- 并行)
def log_info(fun_name):
# logging.info("---->日志开始记录<----")
# fun_name()
# logging.info("---->日志结束记录<----")
# log_info()
# def fun2():
# print("fun2函数的代码运行!")
# 问题:想通过把函数当做变量传值的方式,运行日志函数的时候,也能过打印fun2函数,并且print的信息要放在日志打印的之间?
# 1.调用log_info函数
# log_info()
# 2.给log_info函数设置参数,用来接收fun2的函数本体
# 3.需要把fun2的函数本体,当做变量传递给log_info的参数fun_name
# log_info(fun_name=fun2)
# 4.把接收进来的fun2函数本体,在日志打印之间进行调用,也就是fun_name()
装饰器
可以在原有的函数之前、之后进行代码的补充(强化)
语法规则:
def 外层函数(设置一个参数,用来接收调用函数的本体):
def 内置函数():
你要添加的前/后的代码补充
return 内置函数的名称
普通的函数嵌套
# def zsq():
#
# def nzhs():
# print("nzhs的打印信息")
# # pass # 让程序直接跳过这部分的代码,也不报错
#
# nzhs()
#
#
# zsq()
示例:
# def log_zsq(fun_name):
# def log_info():
# # print(f"fun_name的值:{fun_name}") # <function fun3 at 0x7fb7d017d430>
#
# # 既然fun_name的值是fun3函数的本体,那么只要添加一个括号,就可以运行fun3函数的代码
# # fun_name()
#
# print("1")
# fun_name()
# print("2")
#
# return log_info
#
#
# @log_zsq
# def fun3():
# print("fun3函数的打印信息!")
#
#
# fun3()
# 问题:在不改变fun3函数里面的代码同时,在他的前面/后面加一些代码,怎么办?
# 例如:在前面加一个打印"1",在后面加一个打印"2"
# 1.在原有函数的头部,添加一个@符号,然后跟着装饰器的函数名称(不要带括号)
# 2.获取fun_name的值,应该是什么? -- fun3函数的本体
# 3.调用fun3函数
# 4.按照需求,完成代码的补充
装饰器的传参
# def login_zsq(fun_name):
# def login_nzhs(username, password):
# print(f"username:{username}")
# print(f"password:{password}")
#
# # if username == "admin" and password == "123456":
# # print("账号验证成功,允许登录")
#
# fun_name(username, password) # 此时在调用fun4函数,但是fun4函数定义了两个参数,并未传值
#
# return login_nzhs
# @login_zsq
# def fun4(username, password):
# if username == "admin" and password == "123456":
# print("账号验证成功,允许登录")
# fun4(username="admin", password="123456")
# 调用装饰器的时候,第一次传参,先给谁?
# 装饰器里面的内置函数,需要定义参数用来接收
# 既然内置函数可以接收值,那么原函数fun4怎么接收传进来的值?
# 在装饰器里面调用原函数执行的时候,把参数同时传递给他
知识点检查
"""
1.定义装饰器的规则
2.怎么调用/使用装饰器
3.怎么接收调用原函数时,传入的值
4.原函数,怎么接收传进来的值
"""
# 1.定义装饰器的规则
def login_zsq(fun_name):
def login_nzhs(username, password):
print(f"username: {username}")
print(f"password: {password}")
if username == "admin" and password == "123456":
print("账号识别成功,允许登录!")
user = "七夜老师"
sex = "man"
age = 18
fun_name(user, sex, age)
return login_nzhs
# 2.怎么调用/使用装饰器
@login_zsq
def fun1(user, sex, age):
print(f"""
=====自我介绍=====
user: {user}
sex: {sex}
age: {age}
""")
# 3.怎么接收调用原函数时,传入的值
fun1(username="admin", password="123456")
# 4.原函数,怎么接收传进来的值
# 如何打断点,怎么调试代码
# 手动设置中断程序运行的节点 -- 断点
# 断点调试,只生效于DEBUG模式
模块
模块的概念
包(package)和模块(module)
包就是python中的文件夹(图标有小圆点、有一个init.py文件)
模块就是我们的文件名(不包含.py) 举例:模块的概念
示例:
import time # 模块 # print(time.time()) # 当前时间的时间戳 # time.sleep(3) # 强制等待x秒 # from 模块的路径 import ... # from 包/模块 import 方法/函数/类/变量/其他的数据信息... # from time import sleep # from time import * # sleep(3)
文件操作
文件读取
磁盘:C盘... 500G、1TB、4TB
内存:内存地址,临时存储的空间 16G、24G、32G、64G
python 能够直接读取计算机文件 -- txt、excel、docx、csv、yaml...
语法规则:
open('文件路径', mode='读取方式', encoding='编码格式')
mode: r 读取 w 写入 a 追加写入
直接copy的路径,容易存在转义字符的情况,在引号的前面加一个小写的 r -- 防转义
file = open(r'/Volumes/attached/hcedu/vipCourse/pythonBasic/python_code/python_0307_234/day07/03 文件操作/load_txt',
mode='r', encoding='utf-8')
# 读取文件 -- read()
# msg = file.read()
# print(f"读取到的内容:{msg}")
# 关闭文件 -- close()
# file.close()
# msg1 = file.read()
# print(f"读取到的内容:{msg1}")
# 问题:那么此时,msg还有没有值?可以的,因为变量的值已经存储在内存中了
# print(f"读取到的内容:{msg}")
# 按行读取 -- readline()
# msg2 = file.readline()
# print(f"读取到的内容:{msg2}")
# 读取所有的内容,按行划分列表元素 -- readlines()
# msg3 = file.readlines()
# print(f"读取到的内容:{msg3}")
# print(len(msg3))
文件写入
# w:覆盖写入
# a: 追加写入
示例:
file = open("/Volumes/attached/hcedu/vipCourse/pythonBasic/python_code/python_0307_234/day07/03 文件操作/load_txt1",
mode="a", encoding="utf-8")
# w:覆盖写入
# a: 追加写入
# 直接写入 -- write()
file.write("这个是我想写入的内容\n")
file.write("这个是我想写入的内容\n")
file.write("这个是我想写入的内容")
file.write("这个是我想写入的内容")
file.close() # 养成好习惯
九、异常机制处理
异常机制
try和except
异常:程序无法继续执行了,例如:字符串和数字相加,除以0,对None进行操作
中断当前程序执行,然后打印出红字Exception
error
捕捉异常的方式:关键字
try: 代码块(逻辑) except 异常类型(Exception): 代码块(出异常之后,会执行这里)
示例:
str1 = input("请输入8个长度以外的字符串:")
try:
print(f"获取输入字符串的第八个值:{str1[7]}")
# unexpected EOF while parsing except Exception as e:
# 获取异常的信息,然后赋值给变量 e
print(f"报错的异常为: {e},请检查!!!")
print("欢迎来到七夜老师的课堂!")
注意:
一旦try的代码块运行完成,没有报错,就不会去运行except
当str1没有8个长度的值出现,那么str1[7]的代码是不是会报错?会
可以提前设置异常处理机制,可以清晰的定位问题,并且不妨碍程序运行
获取报异常的信息,并且可以打印出来
try和finally
-
try...except 捕获异常,出异常了执行except代码块的内容
-
try...finally
try: 代码块 finally: 无论异常是否发生,finally代码块内容一定会执行
示例:
try:
print("try下面的代码块执行!")
print("报错前的代码")
n = 1 / 0
# 一定会报错
print("报错后的代码")
except:
print("except下面的代码块执行!")
n = 1 / 0
finally:
print("finally下面的代码块执行!")
#问题:try执行代码的时候,遇到了报错的代码,那么之前的代码是否会执行?会
#但是,报错后的同级代码,不会运行
注意:
-
无论try和except会不会报错,finally都会执行
-
只有try报错了,才会运行except
-
如果try报错,并且except里面也报错了,会同时打印报错信息
练习:
try:
print("最外层 -- try代码块")
try:
print("里面 -- try代码块")
n = 1 / 0
except:
print("里面 -- except代码块")
n = 1/0
except:
print("最外层 -- except代码块")
# 问题:如果正常执行,会打印哪几行的代码?
# 如果存在多个try、except的嵌套 -- 遵循try和except的运行逻辑,try不报错,就不会运行except
# 问题:在最外层的try里面,加了报错代码,会打印哪几行?
# 一旦遇到报错的代码,就不会执行同级代码
# 问题:在里面层的try里面,加了报错代码,会打印哪几行?
# 里面这层try、except已经做了正常的异常处理之后,就表示try已经全部运行成功
assert异常
断言:预期结果 == 实际结果
断言:用关键字 assert + 表达式(表达式返回一个bool值)
我希望是一个什么结果 -- 元素定位,assert 标签是否存在 True False
如果表达式是False,就会出异常,后面可以加提示
示例:
username = input("请输入登录的账号:")
password = input("请输入登录的密码:")
if username == "admin" and password == "123":
print("欢迎成功登录七夜老师的用户系统!")
assert username == "admin" and password == "123", f"Use case does not pass, please check data! username:{username}, passowrd:{password}"
print("欢迎成功登录七夜老师的用户系统!")# 为什么用例需要用断言来做处理?
# 一条自动化用例,如果代码全部运行通过,没有报错,视为用例通过
# 反之,如果一旦报错,就视为用例失败




3858





