python基础笔记

python基础

数据输入input()和输出print()

无论键盘输入什么类型的数据,input()获取的数据永远是字符串类型

1 输入  input(msg)
    参数msg: String 提示信息
    返回值: String 输入的信息
2 输出  print(*arg, sep=' ', end='\n')
  参数:
    *args: 不定长参数,要输出的数据,不定长个数据
	sep=' ': 输出的各数据中间的分隔符 默认是空格' '
    end='\n': 输出的结束符 默认是换行'\n'
num = input("提示信息")
num1 = int(num)#input获取的数据都是字符串类型,按需自行转换为其他类型
print(num1)
"""直接print()相当于java中的println()"""
#不输出换行符(相当于java中的print())
print("...",end='')
print("123")
#...123

#设置数据中间的分割符为/
print("1","2","3",sep='/')#1/2/3

 #返回字面量或变量存储的数据的数据类型<class ''>
type()
#数据类型转换(字符串转数字,数字转字符串)
int(x)		#将x转换为一个整数
float(x)	#将x转换为一个浮点数
str(x)		#将对象x转换为字符串	
	#同type一样,都是带有结果的(返回值),可用print字节输出,也可以用变量存储
    #万物皆可转字符串,但字符串转数字,需确保字符串内容都是数字才行
    #浮点数转整数会丢失精度

标识符

用户编写代码时,对变量、类方法等编写的名字,叫做标识符

命名规则:

​ 1、内容限定:

​ 标识符命名中,只允许出现:.英文 .中午 .数字 .下划线(_)

​ 注意 :数字不可以开头(不推荐使用中文)

​ 2、大小写敏感(区分大小写)

​ 3、不可使用关键字(与关键字大小写不一致可以使用)

命名规范:(不同于规则的强制性,规范是建议性要求)

​ .变量名 .类名 .方法名 (不同的表示符有不同的规范)

​ 1、变量名:

​ 1)见名知意

​ 2)下滑线命名法:多个单词组合变量名,要使用下滑线做分隔

​ 3)英文字母全小写:命名变量中的英文字母,应全部小写

运算符

#算数运算符
+ - * / 
//(整除) %(取余) **(平方) 2**3=8
#赋值运算符
=
#复合赋值运算符
+= -= *= /= %= **= //=
c**=a 等效于 c=c**a

字符串

字符串的三种定义方式

1、‘单引号定义法’ 2、“双引号定义法” 3、“”“三引号定义法”“”

三引号定义法,和多行注释,同样支持换行操作,不使用变量接受它,就可以作为多行注释使用

引号的嵌套

单引号定义法包含双引号,双引号定义法包含单引号

可以使用:转移字符(\)来将引号解除效用,变成普通字符串

字符串的拼接(+)

(使用“+”,一般用于字面量和变量之间使用拼接)

#字符串字面量之间的拼接(+)
print("奔波霸"+"霸波奔")
#字符串字面量和字符串变量的拼接(+)
name="我重伤倒地"
print(name+",但还活着")
"""注意:无法通过+拼接 字符串 和 非字符串类型"""
字符串格式化(%s %d %f)

(使用%占位,再用变量填补,可用于字符串与非字符串进行拼接)

语法:"%占位符"%变量

#通过占位的形式,完成拼接
name="我重伤倒地"
print("%s,但还活着"%name)
"""
多个变量占位
变量要用括号括起来,以逗号分隔
并按照占位顺序排入
"""
#通过占位的形式,完成数字和字符串的拼接
class_num = 57
avg_salary = 16781
message = "该python课程共有%s期,毕业平均工资:%s" % (class_num,avg_salary)
print(message)

%表示:我要占位

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

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

使用辅助符号“m.n”来控制数据的宽度和精度

  • m,控制宽度,要求是数字(很少使用),设置的宽度小于数字本身,m不生效,大于则用空格补足
  • n,控制小数点精度,要求是数字,会进行小数的四舍五入

实例:

  • %5d:表示宽度为5的整数,如数字11=》【空格】【空格】【空格】11
  • %1d:宽度为1的整数,(宽度小于数字本身不生效)如数字11=》11
  • %5.2d:宽度为5小数点精度为2的整数,如数字11=》【空】【空】【空】11
  • %6.2f:宽度为5小数点精度为2的浮点数,如数字11.345=》【空格】11.35
  • %.2f:不限制宽度,小数点精度为2,如11.234=》11.35
字符串格式化方式2(f"快速{格式化}")

语法:f"内容{变量}{变量}"(f就是format格式化的首字母)

特点:(原本什么样就输出什么样)适合对精度没有要求的时候快速使用

  • 不限制数据类型
  • 不做精度控制
name="铁驭"
num1=3
print(f"协议{num1},保护{name}")
对表达式进行格式化 (无需使用变量时简化代码)

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

如:1+1、5*2,就是表达式,因为有具体结果

如:name=“张三”、age=11+11,”=“右侧的都是表达式,有具体结果,具体结果赋值给了左侧变量

  • f"{表达式}"
  • "%s\%d\%f" % (表达式、表达式、表达式)
print("协议%d,保护%s" % {3,"铁驭"})
print(f"协议{1*3},保护{铁驭}")
print("字符串再Python中的类型是:%s" % type{'字符串'})
"""再无需使用变量进行数据存储的时候,可直接格式化表达式,简化代码"""

比较运算符

>	<	>=	<=	
==	!=(可用于字符串)
#计算结果为布尔类型
True	False

判断语句(if…elif…else…)

if 判断条件:True时,执行的代码块
elif 判断条件2:	
    执行的代码块
else:
    都不成立时,执行的代码块
"""不要忘记冒号":" """
"""每个代码块前要有相同的缩进,一般用4个空格/一个tab"""

循环语句(while…/for…)

flag = True#也可以用1和0代替,1为True,0
while 条件flag:
	条件为True时,执行的代码块
    if 终止条件:
    	flag = False
    while 条件2:
        条件2True时,执行的代码块
#条件为True继续,False停止
#规划好终止条件,防止无线循环
    

#对待处理数据集中的元素挨个取出,并在每次循环赋值给当前临时变量
for 临时变量 in 待处理数据集(序列):
    循环条件满足时执行的代码#(处理当前循环的临时变量或其他代码)
#注意#
"""for循环无法定义循环条件,只能被动取出数据处理"""
循环嵌套
for循环 或 while循环:
	循环满足条件应做的事
	for循环 或 while循环:
		循环满足条件应做的事
#注意缩进
#for循环和while循环可以相互嵌套使用
range语句

带处理数据集,严格来说,称之为:序列类型

序列类型

指,其内容可以一个个依次取出的一种类型,包括:(字符串 列表 元组 等)

#获取从0开始,到num结束的序列(不含num本身)
#例:range(5)取得数据是:[0,1,2,3,4]
range(num)
#获取从num1开始,到num2结束的序列(不含num2本身) 
#例:range(5,10)取得数据是:[5,6,7,8,9]
range(num1,num2)
#获取从num1开始,到num2结束的序列(不含num2本身) ,且步长为step(step默认为1)
#例:range(5,10,2)取得数据是:[5,7,9](从5开始,查两个取一个)
range(num1,num2,step)for循环遍历输出range序列
for x in range(4,10,2):
    print(x)
#4
#6
#8
变量作用域

for循环中的临时变量,其作用域限定为:循环内

这种限定:

  • 是规范限定,非强制限定
  • 不遵守也正常运行,但不建议这样做
  • 如需访问临时变量,可以预先在循环外定义它
i = 0
for i in range(4,10,2):
    print(i)
print(i)    
循环中断break和continue
continue:中断本次循环,直接进入下一次循环(暂时跳过某次循环,直接进行下一次)
break:直接结束循环
两者都可以用于:forwhile循环,效果一致

for i in range(1,10):
    语句1
    for x in range(1,10)
    	语句2
    	break
    	语句3
	语句4 
yuer = 10000
for i in range(1,21):
    import random
    num = random.randint(1, 10)
    if num <= 5:
        print(f"员工{i},绩效分{num},低于5,不发工资,下一位")
        continue
    if yuer == 0:
        print("工资发完了,结束发工资")
        break
    else:
        yuer -= 1000
        print(f"向员工{i}发放工资1000元,账户余额还剩余{yuer}元")

python函数

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

  • 将功能封装在函数内,可随时随地重复使用
  • 提高程代码的复用性,减少重复代码,提高开发效率
def 函数名(传入参数1,参数2):
	函数体	#函数体遇到return后就结束了
	return 返回值

#调用(并用变量接收返回值)
变量 = 函数名(参数)

'''
1.参数如不需要,可以省略
2.返回值如不需要,可以省略
3.函数必须先定义后使用
'''

None类型

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

用于表示:空、无意义

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

使用场景

  • 用在函数无返回值上

    • 在函数内,不使用return语句既默认返回None/或主动return None
  • 用在if判断上

    • 用在if判断中,None等同于False

    • 一般用于在函数中主动返回None,配合if判断做相关处理

    • def check_age(age):
          if age >= 18:
              return "SUCCESS"
          else:
              return None#可不添加,默认返回None
      
      result = check_age(5)
      if not result:
          print("未成年,禁止进入")
      
  • 用于声明无内容的变量上

    • 定义变量,但暂时不需要变量有具体值,可以用None来代替

    • name = None
      

函数的说明文档

给函数添加说明文档,辅助理解函数的作用

def func(x,y):
	"""
	函数说明
    :param x: 形参x的说明
    :param y: 形参y的说明
    :return: 返回值的说明
    """
    函数体
    return 返回值

通过多行注释的形式,对函数进行说明解释

  • 内容应写在函数体之前

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

func(5,6)#鼠标悬停到传参处,查看函数说明文档

函数的嵌套

在一个函数里面又调用了另外一个函数

流程:函数A中执行到嵌套的函数B,会将函数B全部执行完毕后,再继续执行剩余A的内容

递归:特殊的嵌套,函数嵌套自己

def f_a():
	print("---2---")
def f_b():
	print("---1---")
	f_a()
	print("---3---")
#调用函数f_a    
f_b()
#执行效果
---1---
---2---
---3---

变量的作用域

局部变量:定义在函数内部的变量,在函数外部无法使用(在函数体内部临时保存数据,调用完成后,销毁局部变量)

全局变量:在函数体内、外都能生效的变量

global关键字

使用global关键字可以在函数内部声明变量为全局变量

num = 100
def f_a():
	global num#设置内部定义的变量为全局变量
	num = 200
	print(num)
    
f_a()#200
print(num)#200

ATM银行案例

money = 5000000
name = input("请输入用户的姓名")

def query(show_header):
    if show_header:
        print("----------查询余额----------")
    print(f"{name}您好,您的余额是{money}")

def saving(num):
    global money
    money += int(num)
    print("----------存款----------")
    print(f"{name}您好,成功存款{num}元")

    query(False)

def get_money(num):
    global money
    money -= int(num)
    print("----------取款----------")
    print(f"{name},您好,成功取款{num}元")

    query(False)

def main():
    print("----------主菜单----------")
    print(f"{name}您好,欢迎来到黑马ATM银行,请选择操作:")
    print("查询余额\t[输入1]")
    print("存款\t\t[输入2]")
    print("取款\t\t[输入2]")
    print("退出\t\t[输入4]")
    return input("请输入您的选择:")

while True:
    keyboard_input = main()
    if keyboard_input == "1":
        query(True)
        continue
    elif keyboard_input == "2":
        num = input("您想要存多少钱?请输入:")
        saving(num)
        continue
    elif keyboard_input == "3":
        num = input("您想要取多少钱?请输入:")
        get_money(num)
        continue
    else:
        print("程序退出了")
        break

函数和方法

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

函数的使用:

num = add(1,2)

方法的使用:

student = Student()
num = student.add(1,2)

数据容器(列表、元组、字符串、set、map)

数据容器:一种可以存储多个元素的Python数据类型

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

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

  • 是否支持重复元素
  • 是否可以修改
  • 是否有序,等

分为5类:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)

list列表[ ](有序,可更改,可重复)

可变类型(可重复,任意数据类型的元素,可读可写,每一个位置上的元素可修改)

(可容纳不同类型的元素,有序存储(下标),允许重复数据存在,可以修改)

定义
#列表定义:以[]作为标识,列表内的每一个元素用,逗号隔开 
#字面量
[元素1,元素2,元素3,元素4,...]
#定义变量
变量名称 = [元素1,元素2,元素3,元素4,...]
#定义空变量
变量名称 = []
变量名称 = list()
#嵌套
name_list = [[1,2,3],[4,5,6]]
列表的下标索引

列表的每一个元素,都有编号称之为下表索引

从前向后的方向,编号从0开始递增

从后向前的方向,编号从-1开始递减

(超出下标索引范围,无法去除元素,且会报错)

#列表[下标索引]
name_list = ['Tom','Lily','Rose']
print(name_list[0])	#结果:Tom
print(name_list[1])	#结果:Lily
print(name_list[2])	#结果:Rose

# - 反向索引
print(name_list[-1]) #结果:Rose
print(name_list[-2]) #结果:Lily
print(name_list[-3]) #结果:Tom

#嵌套索引的下标
name_list = [[1,2,3],[4,5,6]]
print(my_list[1][1]) #结果:4
常用操作

除了 定义/使用下标索引取内容 以外,列表也提供了一系列功能(列表的方法)

列表的方法: 插入元素/删除元素/清空元素/修改元素/统计元素个数

列表常见的功能(方法):

使用方式作用
列表.append(元素)追加单个元素(将指定元素,追加到列表的尾部)
列表.extend(其他数据容器)追加一批元素(将其他数据容器的内容取出,依次追加到列表尾部)
列表.insert(下标,元素)插入元素(在指定的下标位置,插入指定的元素)
del 列表[下标]仅删除元素(函数)
列表.pop(下标)删除元素外,并返回被删除元素(方法)
列表.remove(元素)删除某元素在列表中的第一个匹配项
列表.clear()清空列表
列表[下标]=值修改特定位置(索引)的值
列表.index(元素)查找指定元素在列表中的下标,如果找不到报错ValueError
列表.count(元素)统计某元素在列表中的数量,并返回统计结果
len(列表)统计列表中全部的元素数量(列表长度 )
特点

列表(

  • 1.可容纳多个数据,
  • 2.可容纳不同类型的元素,
  • 3.有序存储(下标),
  • 4.允许重复数据存在,
  • 5.可以修改)

学习编程,会学习很多东西,除了经常用的,大多数是记忆不下来的。

我们要做的是,有一个模糊印象,知晓有这样的用法即可。需要的时候查阅资料即可

列表的遍历

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

#while循环
index = 0
while index < len(列表):
	元素 = 列表[index]
    对元素进行处理
    index += 1
#for循环
for 临时变量 in 数据容器:
	对临时变量进行处理

两者的对比:

(for循环更简单,while更灵活)

(for用于从容器内依次取出元素并处理,while用于任何需要循环内的场景)

  • 循环控制上
    • while循环可以自定循环条件,并自行控制
    • for循环不可以自定循环条件,只可以一个个冲容器内取出数据
  • 无限循环上
    • while循环可以通过条件控制做到无限循环
    • for循环理论上不可以,因为被遍历的容器容量不是无限的
  • 使用场景上
    • while循环适用于任何想要的循环的场景
    • for循环适用于,遍历数据容器的场景或简单的固定次数循环场景

tuple元组( )(有序,不可更改,可重复)

(不可变 可重复 任意数据类型的元素 可读)

列表是可修改的

如果想要传递的信息,不被篡改,列表就不合适了

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

最大的不同点在于:

元组一旦定义完成,就不可修改

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

定义

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

#定义元组字面量
(元素1,元素2,元素3,元素4,...)
#定义元组变量
变量名称 = (元素1,元素2,元素3,元素4,...)
#定义空元组
变量名称 = ()			#方式1
变量名称 = tuple()		#方式2
#元组的嵌套
((1,2,3),(4,5,6))

#下标索引取内容
t5 = ((1,2,3),(4,5,6))
num = t5[1][2]
print(num)	#6 

注意:定义单个元素的元组(要在后面加上一个逗号)

#定义单个元素的元组(要在后面加上一个逗号)
#t4 = ("hello")	#<class 'str'>
t4 = ("hello",)	#<class 'tuple'>
print(f"t4类型为:{type(t4)},内容是:{t4}")
相关操作

因为元组的不可修改,所以操作较少

方法作用
元组.index(元素)查找某个数据,如果数据存在返回对应的下标,否则报错
元组.count(元素)统计某个数据在当前元组出现的次数
len(元组)统计元组内的元素个数
注意:
  • 不可以修改元组的内容(但可以修改元组内的list元素内的内容)
特点

元组特点(

  • 1.可容纳多个数据,
  • 2.可容纳不同类型的元素,
  • 3.有序存储(下标),
  • 4.允许重复数据存在,
  • 5.不可以修改(但可以修改元组内的list元素内的内容)
  • 6.支持for循环)

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

元组的遍历
#while循环
index = 0
while index < len(元组):
	元素 = 元组[index]
    对元素进行处理
    index += 1
#for循环
for 临时变量 in 数据容器:
	对临时变量进行处理

字符串

字符串是字符的容器,一个字符串可以存放任意数量的字符,每一个字符就是字符串的一个元素

通过下标索引取值
my_str = "Emotional damage"
value = my_str[2]		#o
value2 = my_str[-16]	#E
print(f"取正向下标为2的元素,值为:{value},取反向下标为-16的索引,值为{value2}")

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

常用操作
操作说明
字符串[下标]根据下标索引取出指定位置字符
字符串.index(字符串)查找给定字符的第一个匹配项的下标
字符串.replace(字符串1,字符串2)将字符串内的全部字符串1,用字符串2替换,不修改原字符串,而是返回一个新的
字符串.split(字符串)按给定的字符串,对字符串进行分割,不会修改原字符串,而是返回一个新的列表
字符串.strip() 字符串.strip(字符串)移除首尾的空格和换行符或指定字符串(是按给定字符串的全部单个字符,来进行移除),返回一个新的字符串
字符串.count(字符串)统计字符串内某字符串的出现次数
len(字符串)统计字符串的字符个数
#例:字符串.strip(字符串)
my_str = "1212asdfasdf1212"
new_my_str=my_str.strip("12")
print(f"字符串{my_str},替换后得到{new_my_str}")
#字符串1212asdfasdf1212,移除后得到asdfasdf
特点

字符串特点(

  • 1.长度任意(取决于内存大小),
  • 2.只存储字符串
  • 3.有序存储(下标),
  • 4.允许重复字符串存在,
  • 5.不可以修改
  • 6.支持for循环)
字符串的遍历
#while循环
index = 0
while index < len(字符串):
	元素 = 字符串[index]
    对元素进行处理
    index += 1
#for循环
for 临时变量 in 字符串:
	对临时变量进行处理

数据容器(序列)的切片

序列

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

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

切片操作

序列支持切片

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

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

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

  • 起始可以省略,视作从头开始(起始下标表示从何处开始)
  • 结束可以省略,视作到尾结束(结束下标(不含)表示何处结束)
  • 步长可以省略,默认步长为1(可以为负数,表示倒序执行)

注意,此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串) (因为考虑到元组和字符串都是不支持修改的)

#对list进行切片,从1开始,4结束,步长1
my_list = [0,1,2,3,4,5,6]
result = my_list[1:4]	#步长默认是1,所以可以不写
print(f"结果1:{result1}")	#结果1:[1,2,3]

#对tuple进行切片,从头开始,到最后结束,步长1
my_tuple = (0,1,2,3,4,5,6)
result2 = my_tuple[:]	#起始和结束不写表示从头到尾,步长为1可以省略
print(f"结果2:{result2}")	#结果2:(0,1,2,3,4,5,6)

#对str进行切片,从头开始,到最后结束,步长2
my_str = "01234567"
result3 = my_str[::2]		
print(f"结果3:{result3}")	#结果3:0246

#对str进行切片,从头开始,到最后结束,步长-1
my_str = "01234567"
result4 = my_str[::-1]		
print(f"结果4:{result4}")	#结果4:76543210

#对列表进行切片,从3开始,到最后结束,步长-1
my_list = [0,1,2,3,4,5,6]
result5 = my_list[3:1:-1]	
print(f"结果5:{result5}")	#结果6:[3,2]

#对元组进行排序,从头开始,到尾结束,步长-2
my_tuple = (0,1,2,3,4,5,6)
result6 = my_tuple[::-2]	
print(f"结果6:{result6}")	#结果6:(6,4,2,0)

set集合{ }(无序(不支持索引),可修改(增/删元素),不可重复(自带去重))

元素是不可变类型

列表可修改,支持重复元素且有序

元组、字符串不可修改、支持重复元素且有序

局限就在于:它们都支持重复元素

如果场景需要对内容作去重处理,列表、元组、字符串就不方便了

基本语法

#定义集合字面量
{元素,元素,......,元素}
#定义集合变量
变量名称 = {元素,元素,......,元素}
#定义空集合
变量名称 = set{}

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

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

集合的常用操作-修改

集合是无序的,所以集合不支持:下标索引访问,所以集合不是序列 (一旦发生改变,元素就会洗牌了)

集合和列表一样,是允许修改的,无法修改元素只能增加和删除元素

常用操作
操作说明
集合.add(元素)集合内添加一个元素
集合.remove(元素)移除集合内指定的元素
集合.pop()从集合中随机取出一个元素
集合.clear()将集合清空
集合1.difference(集合2)得到一个新集合,内含2个集合的差集,(原有的2个集合内容不变)
集合1.difference_update(集合2)在集合1中,删除与集合2中相同的元素,(集合1被修改,集合2不变)
集合1.union(集合2)得到1个新集合,内含2个集合的全部元素(去重),(原有的2个集合内容不变)
len(集合)得到一个整数,记录了集合的元素数量
#添加新元素
	#集合.add(元素)
my_set = {"Geats骑士核心ID","欲望驱动器","马格南升级带扣"}
my_set.add("推进器升级带扣")
my_set.add("欲望驱动器")		#相同元素,会被去重,等于没有添加
print(f"添加元素后的结果{my_set}")
#添加元素后的结果{'推进器升级带扣', '欲望驱动器', '马格南升级带扣', 'Geats骑士核心ID'}

#移除元素
	#集合.remove(元素)
my_set.remove("推进器升级带扣")	#{'欲望驱动器', '马格南升级带扣', 'Geats骑士核心ID'}
print(f"添加元素后的结果{my_set}")

#随机取出一个元素
	#集合.pop()
    #无论取出哪一个元素,该元素在该集合中将不存在
element = my_set.pop()
print(f"集合被取出元素是:{element},取出元素后的集合:{my_set}")	#可能为集合中任意一个元素

#清空集合
	#集合.clear()
my_set.clear()   
print(f"集合清空后,结果是{my_set}") #结果为:set() 	空集合

#取出2个集合的差集
	#语法:集合1.difference(集合2)
	#功能:取出集合1和集合2的差集(集合1有而集合2没有的)
	#结果:得到一个新集合,集合1和就集合2不变
set1 = {1,2,3}    
set2 = {1,5,6}
set3 = set1.difference(set2)
print(set3)	#结果:{2,3}	得到的新集合
print(set1)	#结果:{1,2,3}	不变
print(set2)	#结果:{1,5,6}	不变

#消除2个集合的差集
	#语法:集合1.difference_update(集合2)
	#功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素
	#结果:集合1被修改,集合2不变
set1 = {1,2,3}    
set2 = {1,5,6}
set1.difference_update(set2)
print(f"消除差集后,集合1结果:{set1}")	#结果:{2,3}	不变
print(f"消除差集后,集合1结果:{set2}")	#结果:{1,5,6}	不变  

#2个集合的合并
	#语法:集合1.union(集合2)
	#功能:将集合1和集合2组合成新集合(去重,无序)
	#结果:得到新集合,集合1和集合2不变
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}

#统计集合所有元素的数量
	#语法:len(集合)
    #功能:返回统计该集合中所有元素的数量
set1 = {1,2,3,4,5}
#set1 = {1,2,3,4,5,1,2,3,4,5}	#依旧为5,先去重在统计
num = len(set1)
print(f"集合内的元素数量有:{num}个")

#集合的遍历
	#集合不支持下标索引,不能用while循环
    #可以用for循环
set1 = {1,2,3,4,5}    
for element in set1:
    print(f"集合的元素有:{element}")
    
特点
  • 可容纳多个数据
  • 可容纳不同类型的数据(混装)
  • 数据是无序存储的(不支持下标索引)
  • 不允许重复数据存在
  • 可以修改(增加或删除元素等)
  • 支持for循环

字典 {键值对} dictionary (无序,可更改,有索引(键),不可重复(键必须唯一))

k:不可变类型 必须唯一(不可为字典、列表等)

v:没有要求

#键必须是唯一的,但值则不必。
d = {key1 : value1, key2 : value2, key3 : value3 }
# 使用大括号 {} 来创建空字典
emptyDict = {}
#使用内建函数 dict() 创建字典
emptyDict = dict()

#字典的嵌套
e = {key1 : {vk1:v1,vk2:v2}, key2 : value2}
print(e[key1][vk1])	#v1

访问字典里的值
#不可通过下标索引,而是通过key检索value
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
 
print ("tinydict['Name']: ", tinydict['Name'])
print ("tinydict['Age']: ", tinydict['Age'])
#输出结果
#tinydict['Name']:  Runoob
#tinydict['Age']:  7
#用字典里没有的键访问数据,会输出错误如下
新增元素
d1 = { "aa" : 1 , "bb" : 2 , "cc" : 3 }
#新增
d1["dd"] = 4
print(d1)
修改字典元素
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
 
tinydict['Age'] = 8               # 更新 Age
tinydict['School'] = "菜鸟教程"  # 添加信息

print("tinydict['Age']: ", tinydict['Age'])
print("tinydict['School']: ", tinydict['School'])

#tinydict['Age']:  8
#tinydict['School']:  菜鸟教程
删除字典元素

能删单一的元素也能清空字典,清空只需一项操作。

tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
# 删除键 'Name' 
del tinydict['Name'] 
#或用pop() 
result = tinydict.pop("Name") 
print(f"被删除的元素的参数:{result}") #能返回被删除的参数

# 清空字典
tinydict.clear()   

# 删除字典
del tinydict         
获取全部的key
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
keys = tinydict.keys()
print(keys)	#dict_keys(['Name', 'Age', 'Class'])


#同理dict.values()返回字典的所有值
遍历
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
#方式1:通过获取到全部的key来完成遍历
keys = tinydict.keys()
for i in keys:
	print(f"键为:{i}")
	print(f"值为:{tinydict[i]}")
    
#方式2:直接对字典进行for循环(每一次循环都是直接得到key)
#更简洁
for i in tinydict:
	print(f"键为:{i}")
	print(f"值为:{tinydict[i]}")
    
'''
运行结果为:
键为:Name
值为:Runoob
键为:Age
值为:7
键为:Class
值为:First
'''
常用操作
操作说明
字典[key]获取指定Key对应的Value值
字典[key] = value添加或更新键值对
字典.pop(Key)取出Key对应的Value并在字典内删除此Key的键值对
字典.clear()清空字典
字典.keys()获取字典的全部Key,可用于for循环遍历字典
len(字典)计算字典内的元素数量

注意:新增和更新元素的语法一致 ,如果Key不存在既新增,如果Key存在既更新(Key不可重复)

字典内置函数&方法

Python字典包含了以下内置函数:

序号函数及描述实例
1len(dict) 计算字典元素数量,即键的总数。>>> tinydict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’} >>> len(tinydict) 3
2str(dict) 输出字典,可以打印的字符串表示。>>> tinydict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’} >>> str(tinydict) “{‘Name’: ‘Runoob’, ‘Class’: ‘First’, ‘Age’: 7}”
3type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。>>> tinydict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’} >>> type(tinydict) <class ‘dict’>

Python字典包含了以下内置方法:

序号函数及描述
1dict.clear() 删除字典内所有元素
2dict.copy() 返回一个字典的浅复制
3dict.fromkeys() 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
4dict.get(key, default=None) 返回指定键的值,如果键不在字典中返回 default 设置的默认值
5key in dict 如果键在字典dict里返回true,否则返回false
6dict.items() 以列表返回一个视图对象(返回可遍历的(键, 值) 元组列表)
7dict.keys() 返回一个视图对象(返回字典中所有的key值)
8dict.setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9dict.update(dict2) 把字典dict2的键/值对更新到dict里
10dict.values() 返回一个视图对象
11pop(key[,default]) 删除字典 key(键)所对应的值,返回被删除的值(key - 要删除的键 default - 当键 key 不存在时返回的值)
12popitem() 返回并删除字典中的最后一对键和值
特点
  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 每一份数据是KeyValue键值对
  • 可以通过key获取到Value,Key不可重复(重复会覆盖)
  • 不支持下标索引
  • 可以修改(增加或删除更新元素等)
  • 支持for循环,不支持while循环

1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例:

2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行,如下实例:

tinydict = {['Name']: 'Runoob', 'Age': 7}
print ("tinydict['Name']: ", tinydict['Name'])
#报错
"""
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    tinydict = {['Name']: 'Runoob', 'Age': 7}
TypeError: unhashable type: 'list'
"""

总结

数据容器可以从以下视角进行简单分类:

  • 是否支持下标索引
    • 支持:列表、元组、字符串
    • 不支持:集合、字典
  • 是否支持重复元素
    • 支持:列表、元组、字符串
    • 不支持:集合、字典
  • 是否可以修改
    • 支持:列表、集合、字典
    • 不支持:元组、字符串
列表元组字符串集合字典
元素数量支持多个支持多个支持多个支持多个支持多个
元素类型任意任意仅字符串任意键值对Key:除字典外任意类型Value:任意类型
下标索引支持支持支持不支持不支持
重复元素支持支持支持不支持不支持
可修改性支持不支持不支持支持支持
数据有序
使用场景可修改、可重复的一批数据记录场景不可修改、可重复的一批数据记录场景一串字符的记录场景去重的一批数据记录场景用Key检索Value的一批数据记录场景
数据容器的通用操作 - 遍历

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

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

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

容器通用转换功能

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

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

str() :将给定容器转换为字符串,(给定容器原来打印输出的样子转为字符串)

set() :将给定容器转换为集合,无序去重

​ 字符串转列表/元组,将字符串里的每一个元素都取出来,作为列表/元组的每一个元素

​ 字典转列表/元组,将Value全抛弃掉,只留下Key

容器通用排序功能

sorted(容器,[reverse=False]) ;将给定容器进行排序,reverse默认为False(reverse= True表示倒序排序)

注意:

排序的结果都会变成列表对象,

字典对象按照Key进行排序并抛弃value,

字符按照对应的ASCII码表的码值打小抄进行大小比较,

字符串是按位比较,一位位比较,只要有一位大,那么整体大(既整体字符串中每一位元素的码值的和来进行大小比较)

my_1ist=[3,1,2,5,4]
my_tuple=(3,1,2,5,4)
my_str "bdcefga"	
my-set={3,1,2,5,4}
my_dict={"key3":1,"key1":2,"key2":3,"key5":4,"key4":5}
print(f"列表对象的排序结果:{sorted(my_List)}")
print(f"元组对象的排序结果:{sorted(my_tuple)}")

#列表对象的排序结果:[1,2,3,4,5]
#元组对象的排序结果:[1,2,3,4,5]
#字符串对象的排序结果:['a','b','c','d','e','f",·g']
#集合对象的排序结果:[1,2,3,4,5]
#字典对象的排序结果:['key1','key2','key3','key4','key5']

#反向排序
print(f"列表对象的排序结果:{sorted(my_List),reverse=True}")
print(f"元组对象的排序结果:{sorted(my_tuple),reverse=True}")
print(f"字符串对象的排序结果:{sorted(my_str),reverse=True}")
print(f"集合对象的排序结果:{sorted(my_set),reverse=True}")
print(f"字典对象的排序结果:{sorted(my_dict),reverse=True}")

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

总结

  • 可变数据类型: 列表, 字典(增删,修改value), 集合(增删元素)
  • 不可变数据类型: 数值类型, 字符串, 元组
    • 可变数据类型实现某个功能, 直接改变可变的数据类型;
    • 不可变数据类型实现某个功能,需要将结果赋值给另外一个变量;
  • 是否实现for循环
    • 可迭代数据类型: str, list, tuple, dict, set
    • 不可迭代数据类型:数值类型
  • 是否支持索引(while循环),切片, 重复和连接特性
    • 有序的数据类型: str, list, tuple
    • 无序的数据类型: dict, set

相关链接:https://blog.youkuaiyun.com/Sunny_Future/article/details/79018295

python函数进阶

多个返回值
def test_return():
	return 1,2,"hello"
x,y,z = test_return()	
print(x)	#1
print(y)	#2
print(z)	#hello
按照返回值的顺序,写对应顺序的多个变量接收即可
变量之间用逗号隔开
支持不同类型的数据return
函数的多种传参方式

函数的4种常见参数使用方式:

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

    • 注意:传递的参数和定义的参数的顺序及个数必须一致
  • 2、关键字参数

    • 作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
    • 注意:函数调用时,和位置参数混用时,位置参数必须在前面,而关键字参数之间不分先后顺序
  • 3、缺省参数:也叫默认参数,用于定义参数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)

    • 作用:当调用函数时没有传递参数,就会使用默认用缺省参数对应的值
    • 注意:定义函数时,默认参数必须都定义在最后 ,例子:user_info(name,age=12,gender=‘男’):
  • 4、不定长参数:也叫可变参数,用于不确定调用的时候传递多少个参数(也可不传参)的场景

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

    • 不定长参数的类型 :

      1. 位置不定长传递:以*号标记一个形式参数,以元组的形式接收参数,形式参数一般命名为args(传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组。args是元组类型)

        def 函数名(*args):
        	代码块
        
      2. 关键字不定长传递:以**号标记一个形式参数,以字典的形式接收参数,形式参数一般命名为kwargs(参数是“键=值”形式的情况下,所有的“键=值”都会被kwargs接受,同时会根据“键=值”组成字典)

        def 函数名(**kwargs):
        	代码块
        
    • 注意:args和kwargs都是规范要求,*和**后面可以自定义起名,但建议使用规范写法

'''
位置参数
'''
def user_info(name,age,gender):
	print(f'您的名字是{name},年龄是{age},性别是{gender}')

user_info('TOM',20,'男')

'''
关键字参数
'''
def user_info(name,age,gender):
	print(f"您的名字是:{name},年龄是:{age},性别是:{gender}")

#关键字传参
user_info(name="小明",age=20,gender="男")
#可以不按照固定顺序
user_info(age=20,gender="男",name="小明")
#可以和位置参数混用,位置参数必须在前,且匹配参数顺序
user_info("小明",age=20,gender="男")

'''
缺省参数(默认值)
'''
def user_info(name,age=12,gender='男'):    #默认参数必须都放在最后
	print(f"您的名字是:{name},年龄是:{age},性别是:{gender}")

user_info('小天',13)	#您的名字是:小天,年龄是:13,性别是:男
user_info('小天',13,'女')	##您的名字是:小天,年龄是:13,性别是:女

'''
不定长参数(可变参数)
	位置不定长:
		*号(规范写法:*args)
		接受不定长形参合并为一个数组
	关键之不定长:
		**号(规范写法:**kwargs)
		接收不定长形参(kw格式)组成一个字典
'''
##位置传递用*args(传递进args的不定长数量的形参,合并为一个元组存在)
def user_info(*args):
    print(args)
user_info('TOM')
#结果打印输出('TOM',)    #定义单个元素的元组(要在后面加上一个逗号)
user_info('TOM',18)
#结果打印输出('TOM',18)

##关键字传递用**kwargs(传递进kwargs的不定长数量键值对形参,组成一个字典存在)
#传入参数必须为键值对
def user_info(**kwargs):
    print(kwargs)
user_info(name='TOM',age=18,id=110)
#结果打印输出{'name': 'TOM', 'age': 18, 'id': 110}
匿名函数
函数作为参数传递
def test_func(compute):
	result = compute(1,2)	#确定compute是函数
	print(result)
    
def compute(x,y):
	return x + y

test_func(compute)	#结果:3

传入计算逻辑,而非数据。

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

Lambda匿名函数
#语法格式:
lambda 传入参数:函数体(一行代码,自带return功能)
#lambda是关键字,表示定义匿名函数
#传入参数表示匿名函数的形式参数,如:x,y表示接收2个形式参数
#函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码

注意:

  • 匿名函数用于临时构建一个函数,只用一次的场景
  • 匿名函数的定义中,函数体只能写一行代码,如果函数体要写多行代码,不可用lambda匿名函数,应使用def定义带名函数
def test_func(compute):
	result = compute(1,2)
	print(result)

test_func(lambda x,y:x + y)	#结果:3(匿名函数只可临时使用一次,且只能写一行)

函数的定义中

  • def关键字,可以定义带有名称的函数
  • lambda关键字,可以定义匿名函数(无名称)

有名称的函数,可以基于名称重复使用。

无名称的匿名函数,只可临时使用一次

python文件操作

文件的编码
  • 编码简介

编码就是一种规则集合,记录了内容和二进制间进行相互转换的逻辑。

编码有许多,我们最常用的是utf-8编码

  • 为什么使用编码

计算机只认识0和1,所以需要将内容翻译成0和1才能保存在计算机中。

同时也需要编码,将计算机保存的0和1,反向翻译回可以识别的内容。

一、文件的读取

文件可分为 文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别

1.打开

2.读写

3.关闭

1、打开文件
#open()
#with open()

#open()语法
open(name,mode,encoding)
#示例
f = open('python.txt','r',encoding='UTF-8')
#encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
#此时的f是open函数的文件对象

#with open 语法(在语句块中操作文件,避免忘了close操作)
with open("python.txt","r")as f:
    f.readlines()
#通过在with open的语句块中对文件进行操作
#可以在操作完成后自动关闭close文件,避免遗忘掉close方法

name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)

mode:设置打开文件的模式(访问模式):只读、写入、追加等

encoding:编码格式(推荐使用utf-8)

mode常用的三种基础访问模式
模式描述
r以只读方式打开文件。文件的指针将回放在文件的开头。这是默认模式
w打开一个文件只用于写入。如果该文件已存在则打开文件并覆写(并从头开始编辑,原有内容会被删除)。如果该文件不存在,创建该新文件
a打开一个文件用于追加。如果该文件已存在,则在已有内容之后追加新内容。如果该文件不存在,创建该新文件进行写入
2、读写文件
#read(num)方法:按照num的大小决定读取数据的长度,没有num这表示全读
#readlines()方法:按照行的方式把整个文件读取(一行为一个列表元素),最后返回该列表
#readline()方法:一次读取一行内容

#read()方法
文件对象.read(num)
#num表示要从文件中读取的数据的长度,如果不传num那么就表示读取文件中的所有数据

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

#注意:如果在同一个程序中多次调用read,下一次read会从第一次读取停止处继续往后读(readlines也会受到影响)

#for循环读取文件行
for line in open('python.txt','r'):
	print(f"每一行数据是:{line}")
3、关闭文件
#close()关闭文件对象
f = open('python.txt','r')
f.close()
#最后通过close,关闭文件对象,也就是关闭对文件的占用
#如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用
操作汇总
操作功能
文件对象 = open(file,mode,encoding)打开文件获得文件对象
文件对象.read(num)读取指定长度的字节,不指定num表示读取文件全部(得到的是string类型)
文件对象.readline()读取一行
文件对象.readlines()读取全部行,得到列表
for line in 文件对象for循环文件的行,一次循环得到一行数据
文件对象.close()关闭文件对象
with open() as f通过with open语法打开文件,可以自动关闭
二、文件的写入

写,调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区(暂时先写入内存中)

需要调用flush()刷新,内容才会真正写入文件(真正写入到硬盘中)

​ close包含flush的功能(不使用flush直接用close也可将内容写入硬盘)

​ 这样做是避免频繁操作硬盘,导致频率下降(攒一堆,一次性写硬盘)

文件的写入时打开文件使用模式w

​ 如果写入文件不存在,会自动创建(创建文件无需flush,但内容需flush后才能写入)

​ 如果写入文件已存在,会直接覆写原文件

f = open("D:/python1.txt","w",encoding="UTF-8") 
#文件写入:write(),写入内容(暂时写入到缓冲区(内存)中)
f.write("Hello World!!!")
#内容刷新:flush(),刷新内容到硬盘中
f.flush()
f.close()	#close包含flush的功能,可直接使用close
三、文件的追加

与追加步骤完全相同,将打开文件使用模式a即可

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

a模式,文件存在会在最后,追加写入文件

f = open("D:/python1.txt","a",encoding="UTF-8") 
f.write("Hello World!!!")
f.write("\n你好世界!!!")#加上\n可实现追加换行
f.flush()
f.close()	
#文件的综合案例
'''
将bill.txt文件备份,并将每一行最后一个字段为测试的行筛选掉
'''

fr = open("D:/bill.txt","r",encoding="UTF-8")
fw = open("D:/bill.txt.bak","w",encoding="UTF-8")
for line in fr:
    # if line.count("测试") >= 1:
        # continue
    if line.strip().split(",")[-1] == "测试":
        continue
    fw.write(line)

fr.close()
fw.close()
#验证
f = open("D:/bill.txt.bak","r",encoding="UTF-8")
print(f.read())
f.close()

异常处理(捕获异常)

平常程序遇到bug会有以下两种情况

1、整个程序因为一个bug停止运行

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

真实工作中,我们希望达到2的结果,那这里我们就需要捕获异常

'''
#捕获异常
	捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当针对出现异常的时候,可以有后续手段
#捕获指定异常
	1、如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
	2、一般try下方只放一行尝试执行的代码
#捕获多个异常
	把要捕获的多个异常的类型名,以元组的方式进行书写,并放到except后
可选项
else	finally
注意:均捕获出现的第一个异常	
'''
#1、基本捕获异常	
try:	#一般try下方只放一行尝试执行的代码
    可能发生错误的代码
except:
    如果出现异常,要执行的代码
else:	#异常的else (可选项)
    如果没有出现异常时,要执行的代码
finally:	#异常的finally
    无论是否异常,都要执行的代码
    
#2、捕获指定异常
try:
    #可能发生错误的代码
    print(name)	
except NameError as e:	
    #如果捕获到指定的异常执行的代码
    print('name变量名称未定义错误')	
	#e是异常的对象,记录着异常的具体信息(可打印输出查看)
    print(e)
#3、捕获多个异常
try:
    print(1 / 0)
except(NameError,ZeroDivisionError):
    print('出现了变量未定义 或者 除以0的异常错误')   
    
#4、捕获所有异常
#可直接使用基本捕获异常方法
#也可指定捕获Exception对象(顶级的异常)
try:
    可能发生错误的代码
except Exception as e:
    print('出现了异常错误')   

#示例
try:
    f = open('linux.txt','r')
except:
    f = open('linux.txt','w')
异常的传递

异常是具有传递性的

(报错信息中会显示依次异常传递的位置)

(作用:不需要去最低层,真正出现异常的那句话去捕获,可以通过异常的传递性在高的层级去捕获)

def func01()#异常在funco1中没有被捕获
	print("这是func01开始")
	num 1 / 0
	print("这是func0结束")

    
def func02():	#异常在func02中没有被捕获
	print("这是fuDc02开始")
	func01()
	print("这是func02结束")

    
def main():	#异常在mian中被捕获
    try:
        func02()
    except Exception as e:
        print(f"出现了异常,异常的信息是:{e}")

        
main()

模块

模块导入

模块:以.py结尾的python文件,模块能定义函数、类、变量、可执行代码

作用:我们可以认为一个模块就是一个工具包,通过导入这些模块,帮助我们快速实现一些功能

一般写在代码的开头位置
当导入多个模块时,同名模块或功能,调用到的是后面导入的模块的功能(后一个会把前一个覆盖掉)-----》解决方法:起别名
当导入的模块处字体呈灰色,代表该模块或功能未使用

模块导入方式:

[from 模块名] import [模块||变量|函数|*] [as 别名]

常见的组合方式:

import 模块名
from 模块名 import 类、变量、方法等
from 模块名 import *
import 模块名 as 别名
from 模块名 import 功能名 as 别名

#导入模块调用功能需要 模块.功能()
#导入功能时直接 功能()

ctrl+鼠标左键 可以查看内置模块的源代码

自定义模块

直接创建一个python文件,并写入所需的功能的代码,然后即可导入使用

_ _ main_ _ 变量
if __name__ == __main__:
    代码块
# python文件都会有一个变量__name__,运行时这个变量的名称就会标记为main
# 当前程序运行时__name__会被标记为__main__,则该if判断为true,可以执行后面的代码块

# 用于限制部分操作仅在当前文件运行时执行(例如测试函数等操作),防止调用该模块文件时的执行
_ _ all_ _ 变量
__all__ = ['test','test1']
def test():
    print("test")
def test1():
    print("test1")
def test2():
    print("test2c")    
# __all__变量
# 如果一个模块文件中有__all__=['','']变量时,当使用‘from 模块名 import *’导入时,只能导入这个列表中的元素
# all是使用该方法导入模块时,可使用的元素

#_ _all_ _用于指定使用‘from 模块名 import *’方法导入该模块时,那些功能可以被导入

python包

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

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

包:一个包,就是一堆同类型功能的集合体

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

注意:包下必须有_ _init _ _.py文件,否则只是一个普通文件夹

#导包方式与导模块基本相同
# import my_package.my_module1 as mm1
# mm1.test()
import my_package.my_module1
import my_package.my_module2
my_package.my_module1.test()
my_package.my_module2.test()

from my_package import *

from my_package import my_module1
from my_package import my_module2
my_module1.test()
my_module2.test()

from my_package.my_module1 import test as t1
from my_package.my_module2 import test as t2
t1()
t2()
#此处同包不同模块的功能同名,需要设别名,否则最后的覆盖前面的

在包中的 _ _init _ _ .py文件中添加 _ _all _ _=[ ],用于控制允许导入的模块列表,同样只有在使用from my_package import *方法导包时有效

第三方包安装

python生态非常丰富,有非常多第三方包,能极大帮助我们提高开发效率,第三方没有内置,所以我们需要安装第三方包才能导入使用

安装第三方包:

使用python内置的pip程序

在命令符中输入pip install 包名称即可安装第三方包

速度慢是因为pip默认使用的是国外的网站,可使用以下命令连接国内的网站pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

也可在pycharm中安装,记得勾选上options并添加-i https://pypi.tuna.tsinghua.edu.cn/simple换用国内源

Json数据格式的转换

什么是JSON:是一种轻量化的数据交互格式。可以按照JSON指定的格式去组织和封装数据

JSON本质上是一个带有特定格式的字符串

主要功能:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互,类似于:

  • 国际通用语言-英语

  • 中国56个民族不同地区的通用语言-普通话

python数据(字典、列表)和json数据(字符串)使用dumps和loads相互转换

1、json_str = json.dumps(data)将python数据转化为json数据

如果有中文,可以在data后带上ensure_ascii=False参数来确保中文正常转换

2、py_data = json.loads(data)将json数据转化为python数据

#使用python内置的json模块
import json

# 通过json.dumps(data)方法把python数据转化为json数据
data = [{"name": "老王", "age": 16}, {"name": "张三", "age": 20}]	# 准备符合(json格式)要求的python数据
json_str = json.dumps(data, ensure_ascii=False)

data1 = {"name": "周杰伦", "addr": "台北"}
json_str = json.dumps(data1, ensure_ascii=False)

print(type(json_str))	#<class 'str'>
print(json_str)		#{"name": "周杰伦", "addr": "台北"}
# 通过json.loads(data)方法把json数据转换为python数据
data = '[{"name": "老王", "age": 16}, {"name": "张三", "age": 20}]'
l = json.loads(data)
data1 = {"name": "周杰伦", "addr": "台北"}
d = json.loads(data)

print(type(l))	#<class 'list'>
print(l)	#[{'name': '老王', 'age': 16}, {'name': '张三', 'age': 20}]
print(type(d))	#<class 'dict'>
print(d)	#{'name': '周杰伦', 'addr': '台北'}

pyecharts模块

概况:
Echarts是个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而Python是门富有表
达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时pyecharts诞生了,(echarts适用于Javascript语言,pyecharts是后来推出专用于为python的模块)

工具网站:ab173.com

"""
演示基础折线图的使用
"""
# 导包
from pyecharts.charts import Line
from pyecharts.options import TitleOpts, LegendOpts,ToolboxOpts,VisualMapOpts

# from pyecharts._version import __author__,__version__

# print(__author__)
# print(__version__)
# 得到折线图对象
line = Line()
# 添加x轴数据
line.add_xaxis(['中国', '美国', '英国'])
# 添加y轴数据
line.add_yaxis("GDP", [100, 20, 10])
# 设置全局配置项,通过set_global_opts来设置
line.set_global_opts(
    #标题
    title_opts=TitleOpts(title="GDP展示", pos_left="center", pos_bottom="1%"),
    #图例(默认显示)
    legend_opts = LegendOpts(is_show=True),
    #工具箱
    toolbox_opts=ToolboxOpts(is_show=True),
    #视觉映射
    visualmap_opts=VisualMapOpts(is_show=True)
)
# 生成图表
line.render()
"""
演示地图可视化的基本使用
"""
from pyecharts.charts import Map
from pyecharts.options import VisualMapOpts

# 准备地图对象
map = Map()
# 准备数据
data = [
    ("北京市", 99),
    ("上海市", 199),
    ("湖南省", 299),
    ("台湾省", 399),
    ("广东省", 499)
]
# 添加数据
map.add("测试地图", data, "china")

# 设置全局选项
map.set_global_opts(
    visualmap_opts=VisualMapOpts(
        is_show=True,  # 是否显示
        is_piecewise=True,  # 是否开启手动校准备范围
        #设置在不同范围的颜色显示
        pieces=[
            {'min': 1, 'max': 99, 'label': '1-99', 'color': '#CCFFFF'},
            {'min': 100, 'max': 199, 'label': '100-199', 'color': '#FF6666'},
            {'min': 200, 'max': 299, 'label': '200-299', 'color': '#990033'},
            {'min': 300, 'max': 399, 'label': '300-399', 'color': '#FF9966'},
            {'min': 400, 'max': 499, 'label': '400-499', 'color': '#CC3333'}
        ]
    )
)
# 绘图
map.render()
"""
演示第三个图表:GDP动态柱状图开发
"""
from pyecharts.charts import Bar,Timeline
from pyecharts.options import *
from pyecharts.globals import ThemeType
# 读取数据
f = open('D:/疫情折线图/GDP/GDP数据.csv', 'r', encoding='UTF-8')
data_lines = f.readlines()

# 删除第一条数据
data_lines.pop(0)

# 将数据转换为字典存储,格式为:
# {年份:[[国家,gdp],[国家,gdp],......],年份:[[国家,gdp],[国家,gdp],......]}
# 先定义一个字典对象
data_dict = {}
for line in data_lines:
    year = int(line.split(",")[0])  # 年份
    country = line.split(",")[1]  # 国家
    rate = float(line.split(",")[2])  # GDP(可将科学计数法变为正常的数字)
    # 判断是否是否已经有指定key
    # if year in data_dict:
    #     data_dict[year].append([country, rate])
    # else:
    #     data_dict[year] = [[country, rate]]
    try:
        data_dict[year].append([country, rate])
    except KeyError:
        # data_dict[year] = []
        # data_dict[year].append([country,rate])
        data_dict[year] = [[country, rate]]
# print(data_dict)

# 创建一个时间线对象
timeline = Timeline(
    #主题设置
    {"theme":ThemeType.LIGHT}
)

# 排序年份
sorted_year_list = sorted(data_dict.keys(), reverse=False)  # 设置升序
for year in sorted_year_list:

    data_dict[year].sort(key=lambda element: element[1], reverse=True)
    # 取出本年份前5名国家
    year_data = data_dict[year][:5]
    # 准备数据
    x_data = []
    y_data = []
    for country_gdp in data_dict[year]:
        x_data.append(country_gdp[0])
        y_data.append(country_gdp[1] )
    # 构建柱状图
    bar = Bar()
    #为了满足效果(反转后,GDP最大的在最上)
    x_data.reverse()
    y_data.reverse()
    # 添加数据
    bar.add_xaxis(x_data)
    bar.add_yaxis("GDP(亿)", y_data, label_opts=LabelOpts(position="right"))
    #反转xy轴
    bar.reversal_axis()
    #设置每一年的图表标题
    bar.set_global_opts(
        title_opts=TitleOpts(title = f"{year}全球前5的GDP数据")
    )
    timeline.add(bar,str(year))
#for循环每一年的数据,基于每一年的数据,创建每一年的bar对象
#在for中,将每一年的bar对象添加到时间线中

#设置时间线自动播放
timeline.add_schema(
    play_interval=1000,
    is_timeline_show=True,
    is_auto_play=True,
    is_loop_play=False
)
#通过时间线绘图
timeline.render("GDP动态柱状图.html")

对象

初始对象

理解使用对象完成数据组织的思路

作用:组织数据

对比生活中和程序中:

  • 设计表格,称之为:设计类(class)

  • 生产表格,称之为:创建对象、

  • 填写表格,称之为:对象属性赋值

类的定义和使用
#类的定义和使用
class 类名称:
	类的属性
	
	类的行为
#class是关键字,表示要定义类了
#类的属性,既定义在类中的变量(成员变量)
#类的行为,既定义在类中的函数(成员方法)

#创建类对象的语法
对象 = 类名称()
# 1.设计一个类(类比生活中:设计一张登记表)
class Student:
    name = None  # 记录学生姓名
    gender = None  # 性别
    nationality = None  # 国籍
    native_place = None  # 籍贯
    age = None  # 年龄
    
    def say(self):
        print(f'我是{self.name},这是计划的一部分')
# 2.创建一个对象(类比生活中:打印一张登记表)
stu1 = Student()
# 3,对象属性进行赋值(类比生活中:填写表单)
stu1.name = "罗辑"
stu1.gender = "男"
stu1.nationality = "中国"
stu1.native_place = "北京省"
stu1.age = 31
# 4.获取对象中记录的信息
print(stu1.name)
print(stu1.gender)
print(stu1.nationality)
print(stu1.native_place)
print(stu1.age)
Student.say(stu1)#类调用方法
stu1.say()#对象调用方法(self会自动传入)
成员方法

在类中函数

#在类中
def 方法名(self,形参1,......,形参N):#self必须在参数列表中出现,对象调用传参时可以忽略
    方法体

self关键字是成员方法定义的时候,必须填写的(self出现在形参列表中,但是不占用参数位置,无需理会)

  • 它用来表示类对象自身的意思
  • 当我们使用类对象调用方法的是,self会自动被python传入
  • 在方法内部,想要访问类的成员变量,必须使用self
类和对象

现实世界的事物由属性和行为组成,类也有属性和行为

使用程序中的类,可以完美的描述现实世界的事物

面向对象编程:

​ 类是一种程序中的"设计图纸",需要基于图纸生产实体(对象),才能正常工作

​ 对象是基于图纸生产的具体实体

​ 总结:设计类、基于类创建对象、由对象做具体的工作(使用对象进行编程)

构造方法_ _init _ _()(属性的赋值)

使用_ _init _ _(),称之为构造方法

可以实现:

  • 在创建类对象(构造类)的时候,构造方法会自动执行。
  • 在创建类对象(构造类)的时候,将传入参数自动传递给_ _ init_ _(构造方法)使用。
"""
演示构造方法
"""
class Student:
    #构造方法的参数中以经包含的属性(成员变量)可以省略
    # name = None
    # age = None
    # tel = None
    
    #__init__构造方法,一样需要使用self关键字
    def __init__(self,name,age,tel):
        self.name = name
        self.age = age
        self.tel = tel
        print("创建了一个类对象")

stu1 = Student("汪淼",35,123456)
print(f'{stu1.name},{stu1.age},{stu1.tel}')
魔术方法(常用几种)

魔术方法:前后用_ _包裹的python内置方法

常用的几种

__str__:字符串方法

print(对象)得到的是内存地址,可以通过_ _ str_ _方法,控制类转换为一个我们指定的字符串输出

__lt__ :小于、大于符号比较

__le__:小于等于、大于等于符号比较

__eq__:==符号比较

没有_ _ eq_ _方法,两个对象比较的是内存地址

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # __str__魔术方法
    # 通过__str__控制类转换为指定字符串的行为
    def __str__(self):
        return f"Student对象,name={self.name},age={self.age}"

    # __it__魔术方法
    def __lt__(self, other):
        return self.age < other.age

    # __le__魔术方法
    def __le__(self, other):
        return self.age <= other.age

    # __eq__魔术方法
    def __eq__(self, other):
        return self.age == other.age


stu = Student("周杏轮", 11)
# print(student)      #结果:<__main__.Student object at 0x0000025FCC307C70>
# print(str(student)) #结果:<__main__.Student object at 0x0000025FCC307C70>
print(stu)  # 转化后结果:Student对象,name=周杏轮,age=11
print(str(stu))  # 转化后结果:Student对象,name=周杏轮,age=11

stu1 = Student("01", 12)
stu2 = Student("02", 13)
stu3 = Student("03", 12)
print(stu1 < stu2)  # True
print(stu1 > stu2)  # False

print(stu1 <= stu2)  # True
print(stu1 >= stu2)  # False

print(stu1 <= stu3)  # True
print(stu1 >= stu3)  # True
#没有__eq__方法,俩个对象对比的是内存地址
print(stu1 == stu2)  # False
print(stu1 == stu3)  # True

封装

面向对象编程,是许多编程语言都支持的一种编程思想

简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发

面向对象包含3大主要特征:封装、继承、多态

封装:将现实世界事物在类中描述为属性和方法,即为封装

  • (从而完成程序对现实世界事物的描述)

继承

多态

私有成员(变量、方法)

现实事物有对使用者不公开的属性和行为,作为现实事物在程序中映射的类,相应的就需要定义私有成员

(私有的属性和方法只允许给这个事物本身使用的,而不是用户,同样的在程序中,类中的其他成员(方法\变量)可以访问这些私有的属性和方法)

私有成员的访问限制:

  • 类对象无法访问私有成员
  • 类中的其他成员可以访问私有成员(只能内部使用)

作用:在类中提供仅供内部使用的属性和方法、而不对外开放(类对象无法使用)

#定义私有成员变量和私有成员方法,只需要以_ _开头
# 定义一个类,内含私有成员变量和私有成员方法
class Phone:
    __current_voltage = 0.5  # 当前手机运行电压
    ad = __current_voltage/0.5	#类中的其他成员可以访问私有成员
    def __keep_single_core(self):
        print("让cpu以单核模式运行")
	#类中的其他成员可以访问私有成员
    def call_by_5g(self):
        if self.__current_voltage >= 1:
            print("5g通话已开启")
        else:
            self.__keep_single_core()
            print("电量不足,无法使用5g通话,并已设置单核运行进行省电")


phone = Phone()
#对象无法访问类的私有成员
# phone.__keep_single_core()
# AttributeError: 'Phone' object has no attribute '__keep_single_core'. Did you mean: '_Phone__keep_single_core'?
# print(phone.__current_voltage)
# AttributeError: 'Phone' object has no attribute '__current_voltage'. Did you mean: '_Phone__current_voltage'?
phone.call_by_5g()
print(phone.ad)

继承

基础语法
#单继承
class 类名(父类名):
    类内容体
#多继承
class 类名(父类1,父类2,...,父类N):
    类内容

子类构建的类对象,可以

有自己的成员变量和成员方法

使用父类的成员变量和成员方法

单继承和多继承

单继承:一个类继承一个类

多继承:一个类继承多个类,按照顺序从左向右依次继承

多继承中,如果父类有同名方法或属性,先继承的优先级高于后继承(从左到右)既:先继承的保留,后继承的被覆盖

pass关键字

pass是一个占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思

class my_phone(NFCReader,Phone,RemoteControl):
    #pass关键字:补全语法
    pass
    #没有什么新成员需要补充,有需要保证类的完整性
复写父类方法

复写:在子类中重新定义同名成员即可覆写

调用同名父类成员:

  • 方法1:调用父类成员

    • 使用成员变量:父类名.成员变量
    • 使用成员方法:父类名.成员方法(self)
  • 方法2:使用super()调用父类成员

    • 使用成员变量:super().成员变量
    • 使用成员方法:super().成员方法()

类型注解

在代码涉及数据交互的地方(帮助第三方IDE工具,如PyCharm)提供数据类型的注解,协助做代码提示

开发者自身对变量进行类型的备注

(只是个提示性的备注,不是决定性的,不会影响到程序的运行)(注解错代码也不会报错)

(一般,无法直接看出变量类型时会添加变量的类型详解)

通过ctrl+p查看

'''语法1:变量:类型'''
#基础数据类型注解
var_1:int 10
var_2:float=3.1415926
var_3:bool True
var_4:str "itheima"
#类对象类型注解
class student:
    pass
stu:student = student()
#基础容器类型注解
my_1ist:list=[1,2,3]
my_tuple:tuple (1,2,3)
my_set:set {1,2,3}
my_dict:dict {"itheima":666}
my_str:str "itheima"
#容器类型详细注解    
my_list:list[int][1,2,3]
my_tuple:tuple[str,int,bool]("itheima",666,True)
my_set:set[int]{1,2,3}
my_dict:dict[str,int]={"itheima":666}
#注意:
#元组类型设置类型详细注解,需要将每一个元素都标记出来
#字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value

#除了使用变量:类型,这种语法做注解外,也可以在注释中进行类型注解。

'''语法2:在注释中进行类型注解'''
#语法:
#type:类型
class student:
    pass
stu = student()

import random, json
var_1 = random.randint(1, 10)  # type:int
var_2 = json.loads(data)  # type:dict[str,int]
def func():
	return stu
var_3 = func()  # type:student



'''函数和方法的形参类型注解语法'''
def 函数方法名(形参名:类型, 形参名:类型,......):
	pass
def 函数方法名(形参名:类型, 形参名:类型,......) -> 函数返回值类型:
	pass
#注意返回值类型注解的符号使用:->

def add(x:int, y:int):
	return x + y

def add(x:int, y:int) -> int:
	return x + y

def func(data:list) -> NoneType:
	pass
Union类型(联合类型)

使用Union[类型,......,类型]

可以定义联合类型注解

from typing import Union
my_list:list[Union[str,int]] = [1,2,"itheima","itcast"]
my_dict:dict[str, Union[str,int]={"name":"周杰轮","age":31}

def func(data: Union[int, str]) -> Union[int, str]:
	pass
#func()             

多态

指的是,多个状态,即完成某个同样的行为(函数),使用不同的对象,得到不同的状态

多态指的是,同一个行为,使用不同的对象获得不同的状态。
如,定义函数(方法),通过类型注解声明需要父类对象,实际传入子类对象进行
工作,从而获得不同的工作状态

class Animal:
	def speak(self):
		pass
class Dog(Animal):
	def speak(self):
		print("汪汪汪")
class Cat(Animal):
	def speak(self):
		print("喵喵喵")
image-20230127091402422
抽象类

抽象类:包含抽象方法的类

抽象方法:方法体没有具体实现的方法(pass)

抽象类就好比定义了一个标准,包含了一些抽象方法,要求子类必须实现

抽象类多用于做顶层设计(设计标准)(而不是拿来直接使用的)用子类继承抽象父类并实现抽象方法(实现标准)(以便子类做具体实现)

注意:对子类是一种软性约束,要求子类必须复写(实现)父类的一些方法,并且配合多态去使用,获得不同的工作状态

配合多态,完成

  • 抽象的父类设计(设计标准)
  • 具体的子类实现(实现标准)
class Animal:
	def speak(self):
		pass
class Dog(Animal):
	def speak(self):
		print("汪汪汪")
class cat(Animal):
	def speak(self):
		print("喵喵喵")

"""
这种设计的含义是:
	父类用来确定有哪些方法
	具体的方法实现,由子类自行决定

这种写法,就叫做抽象类(也可以称之为接口)

抽象类:含有抽象方法的类称之为抽象类
抽象方法:方法体是空实现的(pass)称之为抽象方法        
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值