字面量
数字(Number) | 支持:整数(int)、浮点数(float)、复数(complex)、布尔(bool) | 复数:1+2j,以j结尾表示复数 |
---|---|---|
字符串(String) | 描述文本的一种数据类型 | |
列表(List) | 有序的可变序列 | 有序记录一堆数据 |
元组(Tuple) | 有序的不可变序列 | 有序记录一堆不可变的数据 |
集合(Set) | 无序不重复集合 | 无需记录一堆不重复的数据 |
字典(Dictionary) | 无序Key-Value集合 | 无序记录Key-Value型数据 |
注释
- 单行注释:#开头,#和注释内容一般建议以一个空格隔开
- 多行注释:以一对三个双引号引起来,“”“ 注释内容 ”“”
数据操作
-
输出多份数据 格式:print(内容1,内容2,内容3…) 逗号隔开即可
-
也可使用 + 进行拼接,注意,字符串不能通过 + 与int、float等类型拼接
-
查看数据类型:type(被查看类型的数据);python中变量没数据类型,数据又类型
-
数据类型转换
- 数据类型(变量)
- int(“123”)
-
标识符:用户在编程的时候使用的一系列名字,用于给变量、类、方法等命名
-
算术运算符:
- // 取整除,9//2=4
- ** 指数 ,a**b为a的b次方
-
输入数据
- input() :获取键盘输入的数据
- 可以使用:input(提示信息),用以在使用者输入内容之前显示提示信息
- 无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型
-
随机数
-
import random num = random.randint(1,10) #随机生成一个[1,10)范围内的整数
-
# 当预先使用 random.seed(x) 设定好种子之后,其中的 x 可以是任意数字,此时使用 random() 生成的随机数将会是同一个 print ("------- 设置种子 seed -------") random.seed(10) print ("Random number with seed 10 : ", random.random()) # 生成同一个随机数 random.seed(10) print ("Random number with seed 10 : ", random.random())
-
-
print输出
-
print默认换行输出
-
print("Hello",end='') #后面加上 end='' 不换行 print("World",end='')
-
字符串
字符串定义操作
- 单引号定义法:’字符串‘,可以内含双引号
- 双引号定义法:“字符串”,可以内含单引号
- 三引号定义法:“”“字符串”“”,和多行注释的写法一样,同样支持换行操作;使用变量接收它,它就是字符串;不适用变量接收,就可以作为多行注释使用
字符串格式化
-
通过占位的形式拼接字符串
- %s,将内容转换成字符串,放入占位位置
- %d,将内容转换成整数,放入占位位置
- %f,将内容转换成浮点数,放入占位位置
-
""" % 表示 占位 s 表示 将变量变成字符串放入占位的地方 """ name = "张三" message = "我是%s" % name print(message) name1 = "张三" name2 = "李四" message = "我是%s,他是%s" % (name1,name2) print(message)
-
数字精度控制
- 使用 “m.n”来控制数据的宽度和精度
- m,控制宽度,设置的宽度小于数字自身,不生效
- .n,控制小数点精度,会进行小数的四舍五入
- %5d,表示将整数的宽度控制在5位
- %5.2f,宽度控制为5,小数点精度设置为2
- %.2f,只设置精度
-
快速写法
-
f“内容{变量}” (不能做精度控制)
-
name = "张三" print(f"我是{name}")
-
if语句
if 要判断的条件:
条件成立时,要做的事情 #归属于if语句的代码块,前面要有四个空格缩进(用tab缩进即可)
if 要判断的条件:
条件成立时,要做的事情
else:
条件不成立,要做的事情
if 条件1:
条件1满足,要做的事情
elif 条件2:
条件2满足,要做的事情
else:
条件都不满足,要做的事情
循环语句
while 条件:
条件满足要做的事情 #同样基于空格缩进来决定层次关系
i = 1
while i<10:
j = 1
while j<=i:
print(f"{i}*{j}={i*j}\t",end='')
j=j+1
i = i+1
print()
for 临时变量 in 待处理数据集: # for循环无法自定义循环条件,只能从被处理的数据集中,依次
条件满足要做的事情 #取出内容进行处理
range语句 (获得一个简单的数字序列)
- range(num)
- 获取一个从0开始,到num结束的数字序列(不包含num本身)
- range(num1,num2)
- 获得一个从num1开始到num2结束的数字序列(不含num2本身)
- range(num1,num2,step)
- 获得一个从num1开始到num2结束的数字序列,数字之间步长为step
函数
是组织好的、可重复使用的,用来实现特定功能的代码段
def 函数名 (参数):
函数体
return 返回值
#函数要先定义,后使用
#如不需要参数或无返回值,参数、return可省略
def add(x,y):
result = x+y
print(f"{x} + {y} = {result}")
return result
None字面量
None作为一个特殊的字面量,用于表示:空、无意义
- 可用于函数无返回值上
- 用在if判断上
- 用于声明无内容的变量
变量作用范围
- 局部变量
- 作用范围在函数内部,在函数外部无法使用
- 全局变量
- 在函数内部和函数外部都可以使用
- 如何在函数内部使用全局变量
- 使用
global
关键字
- 使用
多返回值
def test_return():
return 1,2 #用,隔开要返回的值
x,y = test_return() # 多个变量接收 用,隔开
print(x)
print(y)
多种参数格式
-
位置参数
-
#传递的参数和定义的参数的顺序及个数保持一致 def user_info(name,age,gender): print(f"您的名字是{name},年龄是{age},性别是{gender}") user_info("zhangsan",20,"男") #常用的传参形式
-
-
关键字参数
-
函数调用时通过 “键=值”形式传递参数
-
可以让函数更加清晰、容易使用,同时也清楚了参数的顺序需求
-
def user_info(name,age,gender): print(f"您的名字是{name},年龄是{age},性别是{gender}") user_info(name="zhangsan",age=20,gender="男") # 也可不按照固定顺序 user_info(age=20,name="zhangsan",gender="男") # 也可和位置参数混用,位置参数必须在前,且匹配参数顺序 user_info("zhangsan",age=20,gender="男")
-
-
-
缺省参数
-
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传默认参数的值(所有位置参数必须出现在默认参数前,包括函数定义和调用)
-
def user_info(name,age,gender="男"): print(f"您的名字是{name},年龄是{age},性别是{gender}") user_info("zhangsan",20) user_info("zhangsan",20,"女")
-
-
不定长参数
-
不定长参数也叫做可变参数,用于不确定调用的时候会传递多个参数(不传参也可以)
-
作用:当调用函数时不确定参数个数时,可以使用不定长参数
-
不定长参数的类型
-
位置传递
-
def user_info(*args): print(args) user_info("zhangsan") user_info("zhangsan",18) #传进的所有参数都会被args变量接收,它会根据传进参数的位置合并为一个元组,args就是tuple类型
-
关键字传递
-
def user_info(**kwargs): print(kwargs) user_info(name="zhangsan",age=18,id="110") #参数是 “键=值” 的形式,所有的“键=值”的参数都会被kwargs接收,同时根据参数的位置组成字典
-
-
-
函数作为参数
-
def test_func(compute): result = compute(1,2) #表示compute是函数 print(result) def compute(x,y): return x + y test_func(compute) #函数compute作为参数,传入了test_func函数中使用 # 计算逻辑的传递,并非数据的传递
-
lambda匿名函数
函数的定义中
- def关键字,可以定义有名称的函数
- lambda关键字,可以定义匿名函数
- 有名称的函数可以基于函数名重复使用
- 无名称的匿名函数,只可临时使用一次
匿名函数定义语法
lambda 传入参数:函数体(一行代码)
-
lambda是关键字,表示定义匿名函数
-
函数体只能写一行代码,无法写多行
-
def test_func(compute): result = compute(1,2) return result test_func(lambda x,y: return x+y)
数据容器
列表(List)
-
列表定义
-
用 [] 作为标识,列表内每一个元素用逗号隔开
-
# 定义空列表 变量名称 = [] 变量名称 = list()
-
列表一次可以存储多个数据,且可以为不同的数据类型,支持嵌套
-
my_list = ["python",True,666,[1,2,3]]
-
-
下表索引取数据
- 正向取数据
- my_list[0] = python
- my_list[1] = True
- my_list[2] = 666
- my_list[3] = [1,2,3]
- 反向取数据
- my_list[-1] = [1,2,3]
- my_list[-2] = 666
- my_list[-3] = True
- my_list[-4] = python
- 正向取数据
-
API
- 查询元素的下标
列表.index(元素)
- 如果元素不存在,会报错
- 修改指定位置的元素值
列表[下标] = 新值
(重新赋值)
- 插入元素
列表.insert(下标,元素)
在指定的下标位置,插入指定的元素
- 追加元素
列表.append(元素)
追加一个元素列表.extend(其他数据容器)
追加将其他数据容器的内容取出,依次追加到列表尾部
- 删除元素
del 列表[下标]
列表.pop(下标)
列表.remove(元素)
删除某元素在列表中的第一个匹配项列表.clear()
清空列表
- 统计某元素在列表内的数量
列表.count(元素)
- 查询元素的下标
-
循环遍历
-
index = 0 while index < len(list) element = list[index] index = index + 1
-
for element in list: process(element)
-
元组(Tuple)
元组同列表一样,都是可以封装多个、不同类型的元素在内,但是元组一旦定义完成,就不能修改
-
元组定义
-
用()做标识,元组内元素用逗号隔开;元组中只有一个元素时,需要在后面加逗号!
-
# 定义空元组 变量名称 = () 变量名称 = tuple()
-
-
利用下标索引获取元素
- 同list可正序、倒叙
-
API
- index() :查找某个元素,如果元素存在返回对应的下标,否则报错
- count():统计某个元素在当前元组出现的次数
- len():统计元组内的元素个数
-
遍历
- 同list
-
元组的拆包与装包
-
#定义一个元组 t3 = (1,2,3) #将元组赋值给变量a,b,c a,b,c = t3 #打印a,b,c print(a,b,c) #当元组中元素个数与变量个数不一致时 #定义一个元组,包含5个元素 t4 = (1,2,3,4,5) #将t4[0],t4[1]分别赋值给a,b;其余的元素装包后赋值给c a,b,*c = t4 print(a,b,c) print(c) print(*c)
-
-
特点
- 可以容纳多个数据,可以容纳不同类型的数据
- 有序存储(可以下标索引)
- 允许重复数据存在
- 不可以修改(如果tuple中嵌套list,可以修改list中的元素)
- 支持遍历
字符串(str)
字符串是字符的容器,一个字符串可以存放任意数量的字符
同元组一样,字符串时一个无法修改的数据容器
-
获取元素
- 字符串同其它容器一样也可以通过下标进行访问
- 从前向后,下标从0开始
- 从后向前:下标从-1开始
-
API
-
字符串.index(字符串)
:查找特定字符串的下标索引值 -
字符串.replace(字符串1,字符串2)
- 将字符串内的全部 “字符串1”替换为“字符串2”
- 不是修改字符串本身,而是得到了一个新的字符串
-
字符串.split(分隔符)
-
按照指定的分隔符,将字符串划分为多个字符串,并存入列表对象中
-
字符串本身不变,而是得到了一个列表对象
-
new_str = str.split(",")
-
-
# 重复输出字符串: * print("hello" * 3) # --hello hello hello # 判断字符串是否包含给定的字符: in, not in print("e" in "a") print("e" not in "a") # --True、False # join():以字符作为分隔符,将字符串中所有的元素合并为一个新的字符串 new_str = '-'.join('Hello') print(new_str) # H-e-l-l-o
-
规整操作
字符串.strip()
去除前后空格、换行符字符串.strip(字符串)
去除前后特定字符串
-
-
特点
- 可以存储字符串
- 长度任意
- 支持下标索引
- 允许重复字符串存在
- 不可以修改
- 支持遍历
序列切片
序列是指:内容连续、有序、可使用下标索引的一类数据容器,列表、元组、字符串均可以视为序列
切片:从一个序列中,取出一个子序列
-
语法
-
序列[起始下标:结束下标:步长]
-
起始下标标识从何处开始,可以留空,留空视作从头开始
-
结束下标(不含)表示从何处结束,可以留空,留空视作截取到结尾
-
步长表示,依次取元素的间隔
- 步长为1表示,一个个取元素
- 步长为2表示,每次跳过1个元素取
- 步长为负数表示,反向取(起始下标,结束下标也要为反向标记)
-
# 切片并输入456 str = "987654321" new_str = str[::-1][3:6] #连续切片 链式编程 print(new_str)
-
集合
-
定义
-
用{}作为标识,元素之间用,隔开
-
# 定义空集合 变量 = set()
-
-
API
- 添加新元素
集合.add(元素)
- 移除元素
集合.remove(元素)
- 取出元素
集合.pop()
- 从集合中随机取出元素
- 会得到一个元素的结果,同时集合本身被修改,元素被移除
- 差集
集合1.difference(集合2)
- 取出集合1和集合2的差集(集合1中有而集合2中没有的)
- 得到一个新的集合,集合1与集合2不改变
- 消除差集
集合1.difference_update(集合2)
- 对比集合1与集合2,在集合1内,删除和集合2相同的元素
- 集合1被修改,集合2不变
- 集合的合并
集合1.union(集合2)
- 将集合1和集合2组合成新集合
- 得到新集合,集合1与集合2不变
- 添加新元素
-
特点
- 集合是无序存储的,所以集合不支持:下标索引访问
- 不允许重复元素存在
- 可以容纳多个数据
- 可以容纳不同类型的数据
- 可以修改
- 支持遍历
字典
-
定义
-
使用{},存储的元素是键值对
-
{key:value, key:value, key:value, ...} #定义空字典 my_dict = {} my_dict = dirt()
-
-
通过key值来取得对应的value
value = my_dict[key]
value = my_dict.get(key)
-
字典的key和value可以是任意数据类型(key不能为字典),字典也是可以嵌套的
-
{ "zhangsan":{"id":"111","age":20}, "lisi":{"id":"222","age":21}, "wangwu":{"id":"333","age":22} }
-
-
API
- 新增元素
字典[key] = value
- 字典被修改,新增了元素
- 更新元素
字典[key] = value
- 字典被修改,元素被更新
- 清楚键值对
字典.pop(key)
- 取出key对应的value并在字典内删除此key的键值对
- 获取全部的key
字典.keys()
- 得到字典中的全部key
- 新增元素
容器通用功能
-
len(容器):统计容器的元素个数
-
max(容器):统计容器的最大元素
-
min(容器):统计容器的最小元素
-
转换
-
list(容器):将指定容器转换为列表
-
字典转列表:只保留key,value会被抛弃
-
字符串转列表:字符串的每个字符作为列表的元素
-
#list可以转成字典,但前提是列表中元素都要成对出现 dict3 = dict([('name','杨超越'),('weight',45)]) print(dict3)
-
-
str(容器):转换为字符串
-
tuple(容器):转换为元组
-
set(容器):转换为集合
-
-
排序
-
sorted(序列,reverse = True):排序,reverse=True标识降序,得到一个新序列
-
# 自定义排序规则 列表.sort(key=选择排序依据的函数,reverse=True|False) my_list=[["a",33],["b",55],["c",66]] def my_sort_key(element): return element[1] my_list.sort(key=my_sort_key,reverse=True) print(my_list)
-
文件操作
open()打开函数
-
open(name,mode,encoding)
-
name:是要目标文件名的字符串,可以包含文件所在的具体路径
-
mode:设置打开文件的模式,只读、写入、追加等
- r:只读方式打开文件(默认模式),文件不存在则报错
- w:写文件;如果文件已存在则打开文件,并从头开始编辑,原有内容会被删除;如果该文件不存在,则创建新文件
- a:文件追加内容。如果文件存在,新的内容会被写入到已有的内容之后,如果文件不存在,创建新文件进行写入
-
encoding:编码格式,推荐使用utf-8
-
f = open("python.txt","r",encoding="utf-8")
-
读文件
-
read()方法:
文件对象.read(num)
- num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
- 多次调用read,下一次read开始读的位置是上一次read结束的位置
-
readlines()
- readlines可以按照行的方式把整个文件的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
- readlines读取的位置也会受上一次read方法的影响
-
readline()
-
一次读取一行
-
read、readlines与readline使用同一个文件指针
-
for line in open("python.txt","r",encoding="utf-8"): print(line)
-
关闭文件
-
f.close()
-
with open语法
-
with open("python.txt","r",encoding="utf-8") as f: for line in f: print(line) # 通过with open的语句块对文件进行操作,可以在操作完成后自动关闭文件,自动close
-
写文件
#1.打开文件
f = open("python.txt","w",encoding="utf-8")
#2.文件写入
f.write("hello world")
#3.内容刷新
f.flush()
"""
直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
当调用flush的时候,内容会真正写入文件
这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写入磁盘)
如果不调用flush,直接调用close,内容也会写入文件,close会调用flush
"""
追加内容
#打开文件,通过a模式打开
f = open("python.txt","a",encoding="utf-8")
#文件写入
f.write("hello world")
#内容刷新
f.flush()
#导入OS模块
import os
#待搜索的目录路径
path = "Day1-homework"
#待搜索的名称
filename = "2020"
#定义保存结果的数组
result = []
def findfiles():
#在这里写下您的查找文件代码吧!
number = 0
for root,dirs,files in os.walk(path):
print(f"当前正在遍历的文件夹:{root}")
print(f"当前文件夹下所有目录的名字:{dirs}")
print(f"当前文件夹中所有文件的名字:{files}")
print("********************")
for name in files:
if filename in name:
number = number+1
result.append([number,os.path.join(root,name)])
for file_result in result:
print(file_result)
if __name__ == '__main__':
findfiles()
异常
#捕获所有异常
try:
代码
except:
出现异常执行的代码
或者
try:
代码
except Exception as e: #Exception为所有异常的父类
出现异常执行的代码
#捕获指定异常
try:
代码
except 指定异常 as e:
出现指定异常执行的代码
#捕获多个异常
try:
code
except(异常1,异常2):
出现异常执行的代码
#else 表示的是如果没有异常要执行的代码
try:
code
except Exception as e:
exception code
else:
没有异常要执行的代码
#finally 无论是否异常都要执行的代码 如关闭文件
try:
f = open("pyhton.txt","r",encoding="utf-8")
except Exception as e:
f = open("python.txt","w",encoding="utf-8")
else:
print("333")
finally:
f.close()
#异常的传递性
def fun1():
num=1/0
def fun2():
fun1()
def main():
try:
fun2()
except Exception as e:
print(e)
"""fun1中发生异常,并且没有捕获处理这个异常,
异常会传递到fun2,当fun2也没有捕获处理这个异常的时候,
main函数会捕获这个异常,这就是异常的传递性"""
模块
模块在使用前需要先导入 导入的语法如下:
[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]
- []表示 :可选的意思,可以不写
#基本语法
import 模块名
from 模块名 import 功能名(*表示全部)
import 模块名 as 别名
from 模块名 import 功能 as 别名
#测试自定模块
if __name__ == '__main__':
测试代码
# pycharm中写main直接补上
#只能当程序是直接运行的时候才会进入if内部,如果是被导入的,if无法进入
#__name__为python内置变量
#这样调用该模块时,测试代码就不会运行,同时又能在自定义模块中保留测试代码,可供测试
# 如果一个模块文件中有`__all__`变量,当使用`from xxx import *`导入时
# 只能导入这个列表中的元素
_all__ = ["test_A"]
def test_A():
print("test_A")
def test_B():
print("test_B")
# 其他包采用 from xxx import *导入该包时 只能导入test_A
包
-
模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含多个模块,但包的本质仍是模块
-
包中包含一个’_init_.py’文件
-
导入包
-
import 包名.模块名
-
#同样可用'__all__=[]',控制允许导入的模块列表,但必须要写在'__init__.py'文件中 # from xxx import *
-
安装第三方包
pip install 包名称 #通过国外站点下载
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称 #通过国内站点
"""
在pycharm中安装->右下角,配置python解释器->interpreter settings->
"""
json
json是一种轻量级的数据交互格式,本质上是一个带有特定格式的字符串,可以按照json指定的格式去组织和封装数据
#json数据的格式:
{"name":"admin","age":18}
[
{"name":"zhangsan","age":23},
{"name":"lisi","age":24},
{"name":"wangwu","age":25}
]
python与json的相互转换
#导入json模块
import json
data = [{"name":"zhangsan","age":16},{"name":"lisi","age":17}]
#通过json.dumps(data)方法将python数据转化为json数据
data = json.dumps(data)
#通过json.loads(data)方法把json数据转化为python数据
data = json.loads(data)
# 为了提高可读性,dumps方法提供了一些可选的参数。
# sort_keys=True表示按照字典排序(a到z)输出。
# indent参数,代表缩进的位数
# separators参数的作用是去掉,和:后面的空格,传输过程中数据越精简越好
import json
data = [ { 'b' : 2, 'd' : 4, 'a' : 1, 'c' : 3, 'e' : 5 } ]
json = json.dumps(data, sort_keys=True, indent=4,separators=(',', ':'))
print(json)
面向对象
class Student:
name = None
def say_hello(self):
print(f"hello,我是{self.name}")
stu_1 = Student()
stu_1.name = "周杰伦"
成员方法
-
self
关键字是成员方法定义的时候,必须填写的 -
它用来表示类对象自身的意思
-
当我们使用类对象调用方法的时候,self会自动被python传入
-
在方法内部,想要访问类的成员变量,必须使用self
-
def 方法名 (self,形参1,形参2): 方法体
私有成员
- 私有成员变量:变量名以__开头(两个下划线)
- 私有成员方法:方法名以__开头(两个下划线)
- 私有方法不能直接被类对象 使用,私有变量无法赋值,也无法取值
构造方法
-
__init__()
方法称为构造方法 -
创建类对象时,自动执行,将传入参数自动传递给
__init__
方法使用 -
在方法内使用成员变量需使用
self
-
class Student: name = None age = None tel = None def __init__(self,name,age,tel): self.name = name self.age = age self.tel = tel stu = Student("周杰伦",18,"15633333333")
魔术方法
-
字符串方法
__str__()
-
控制类转换为字符串的行为,Java中的
toString()
方法 -
class Student: def __int__(self,name,age): self.name = name self.age = age def __str__(self): return f"Student类对象,name={self.name},age={self.age}"
-
-
大于小于符号比较方法
__lt__()
-
直接比较两个对象是不可以的,但在类中实现
__it__
方法,即可同时完成:小于符号和大于符号 2种比较。 -
运算符重载
-
class Student: def __init__(self,name,age): self.name = name self.age = age def __lt__(self,other): return self.age < other.age
-
-
大于等于、小于等于比较运算符
__le__()
-
class Student: def __init__(self,name,age): self.name = name self.age = age def __le__(self,other): return self.age <= other.age
-
-
等于运算符
__eq__()
-
class Student: def __init__(self,name,age): self.name = name self.age = age def __eq__(self,other): return self.age == other.age
-
继承
class 类名(父类1,父类2,...):
类内容体
# 子类没有新内容的话,类体可用pass关键字表示无内容,空的意思,补全类定义的语法
复写
-
子类继承父类的成员属性和成员方法后,可以进行复写(Java中的重写)
-
在子类中重新定义同名的属性或方法即可
-
class Phone: IMEI = None producer = "ITCAST" def call_by_5g(self): print("5g通话中") class MyPhone(Phone): producer = "ITHEIMA" def call_by_5g(self): print("子类的5g通话")
调用父类成员
- 使用父类成员
- 父类名.成员变量
- 父类名.成员方法(self)
- 使用super()调用父类成员
- super().成员变量
- super().成员方法()
类型注解
-
类型注解:在代码中设计数据交互的地方,提供数据类型的注解
-
主要功能:
- 帮助第三方IDE工具对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行类型注释
-
支持:
- 变量的类型注解
- 函数(方法)形参列表和返回值的类型注解
-
语法:
-
变量:类型
-
var_1: int = 10 var_2: bool = True var_3: str = "123" my_list: list[int] = [1,2,3] my_tuple: tuple[str,int,bool] = ("itheima",123,True) my_set: set[int] = {1,2,3} my_dirt: dict[str,int] = {"itheima":666} stu_1: Student = Student()
-
注释中进行类型注解
# type:类型
-
var_1 = randonm.randint(1,10) # type:int var_2 = json.loads(data) # type:dict[str,int] var_3 = Student() # type:Student
-
-
方法的类型注解
-
def 方法函数名(形参名:类型,形参名:类型...): # 形参注解 方法体 def 方法函数名(形参名:类型,形参名:类型...)->返回值类型: 方法体
-
-
类型注解只是提示性的,并非决定性的,数据类型和注解类型不匹配也不会导致错误
-
联合类型注解
-
# Union[类型,...,类型] from typing import Union # my_list中既可存int类型又可以存str类型 my_list: list[Union[str,int]] = [1,2,"itheima","itcast"] my_dict: dict[str,Union[str,int]] = {"name":"zhoujielun","age":13} # 对函数使用联合型注解 def fun(data: Union[int,str])->Union[int,str]: pass
-
多态
-
抽象类
-
含有抽象方法的类称为抽象类
-
抽象方法:方法体是空实现的(pass)
-
class Animal: def speak(self): pass class Dog(Animal): def speak(self): print("汪汪汪") class Cat(Animal): def Speak(self): print("喵喵喵")
-
闭包
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个是用外部函数变量的内部函数称为闭包
- 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
- 闭包使用的变量的作用域在函数内,难以被错误的调用修改
# 简单闭包
def outer(logo):
def inner(msg):
print(f"<{logo}>{msg}<{logo}>")
return inner
fn1 = outer("黑马程序员")
fn1("大家好")
fn2 = outer("传智教育")
fn2("大家好")
# 修改外部函数变量的值
# 需要使用nonlocal关键字修改外部函数的变量,才可在内部函数中修改它
def outer(num1):
def inner(num2):
nonlocal num1
num1 = num1+num2
print(num1)
return inner
fn = outer(10)
fn(10)
fn(10)
装饰器
装饰器就是使用创建一个闭包函数,在闭包函数内调用目标函数
可以达到不改动目标函数的同时,增加额外的功能
# 使用闭包实现装饰器
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我睡醒了")
return inner
def sleep():
import random
import time
print("睡眠中。。。。。")
time.sleep(random.randint(1,5))
fn = outer(sleep)
fn()
# 语法糖写法
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我睡醒了")
return inner
@outer
def sleep():
import random
import time
print("睡眠中。。。。。")
time.sleep(random.randint(1,5))
sleep()
设计模式
-
单例模式
-
保证一个类只有一个实例,并提供一个访问它的全局访问点
-
节省内存,节省创建对象的开销
-
# StrTools类 class StrTools: pass str_tool = StrTools() # test.py from StrTools import str_tool str1 = str_tool str2 = str_tool print(id(str1)) print(id(str2))
-
-
工厂模式
-
将对象的创建 由使用原生类本身创建 转换到 由特定的工厂方法来创建
-
好处
- 大批量创建对象的时候有统一的入口,易于代码维护
- 当发生修改时,仅修改工厂类的创建方法即可
-
class Person: pass class Worker(Person): pass class Student(Person): pass class Teacher(Person): pass class Factory: def get_Person(self,p_type): if p_type == "w": return Worker() elif p_type == "s": return Student() else: return Teacher() pf = Factory() worker = pf.get_person("w") student = pf.get_person("s") teacher = pf.get_person("t")
-
多线程
# python的多线程通过threading模块来实现
import threading
thread_obj = threading.Thread([group [,target [, name [,args [, kwargs]]]]])
# group:暂时无用,未来功能的预留参数
# target: 执行的目标任务名
# args: 以元组的方式给执行任务传参
# kwargs: 以字典方式给执行任务传参
# name: 线程名,一般不用设置
# 启动线程,让线程开始工作
thread_obj.start()
import time
import threading
def sing(msg):
while True:
print("msg")
time.sleep(1)
def dance(msg):
while True:
print("msg")
time.sleep(1)
sing_thread = threading.Thread(target = sing,args = ("我在唱歌",))
dance_thread = threading.Thread(target = dance,kwargs = {"msg":"我在跳舞"})
sing_thread.start()
dance_thread.start()
正则表达式
python正则表达式,使用re模块,并基于re模块中的三个基础方法来做正则匹配
分别是:match、search、findall 三个基础方法
- re.match(匹配规则,被匹配字符串)
- 从被匹配字符串开头进行匹配,匹配成功返回匹配对象(包含匹配的信息),开头匹配不成功返回空
- search(匹配规则,被匹配字符串)
- 搜索整个字符串,找出匹配的,找到第一个后,就停止,不会继续向后;找不到就返回None
- findall(匹配规则,被匹配字符串)
- 匹配整个字符串,找出全部匹配项;找不到返回空list[]