本周总结
字典,元组,集合内置相关操作
-
字典
#字典必须掌握的操作 user_dict = {'username': 'pig', 'password': 111, 'happy': ['ren', 'misuy', 'rong']} 1.按k取值,k不在字典里的话会直接报错 2.内置方法get,get取值如果字典里面没有建就默认返回Nome,可以通过第三行代码展示第二个参数自定义返回名称 3.修改数据值,可以将自己需要改的建输入,让后在等于自己需要修改的数据即可修改 user_dict['username'] = 'oiuio' print(user_dict) # username 中的pig 修改成 oiuio 4.新增键对值 user_dict['moye'] = 1996 print(user_dict) # 会在字典内最末端增加 'moye': 1996 5.删除数据 del user_dict['happy'] # 删除happy print(user_dict) 6.统计字典中键值对的个数 # 关键字len print(len(字典的变量名)) # 7.一次性取所有的键 keys() print(user_dict.keys()) # 值去掉取键,只要键 # 8.一次性取所有值 values() print(user_dict.values()) # 键去掉取值,只要值 # 9.一次性获取所有键对值数据 items() print(user_dict.items()) '当第二个公共值是可变类型的时候 一定给要注意通过任何一建的修改都会影响所有'
-
元组
1.类型转换 tuple() 只要是支持for循环的数据类型都可以转换成元组 2.元组必须掌握的方法 t1 = (11, 22, 33, 44, 55, 66) # 1.索引取值 print(t1[]) 填入需要的取值 起始值为0 支持复数 # 2.切片操作 print(t1[ : ]) 默认顺序从左往右 可以使用复数修改方向 # 3.间隔,方向 print(t1[ : : ]) 第三个不填默认是1 # 4.统计元组内的数据值个数 print(len(t1)) # 5.统计元组内指定数值出现次数 print(t1.count(11)) # 6.统计元组内指定数据值的索引值 print(t1.index(22)) # 7.元组内只有一个值逗号不能少 # 8.元组内索引绑定的内存地址不能被修改 # 9.元组不能新增或者删除数据
-
集合
1.类型转换 set() 集合内数据必须是不可变类型(整形 浮点型 字符串 元组) 集合内数据是无序数据 没有索引的概念 2.去重 3.关系运算
字符编码理论
该知识点理论特别多 但是结论很少 代码使用也很短
1.字符编码只针对文本数据
2.回忆计算机内部存储数据的本质
3.既然计算机内部只认识01 为什么我们却可以敲出人类各式各样的字符
肯定存在一个数字跟字符的对应关系 存储该关系的地方称为>>>:字符编码本
4.字符编码发展史
4.1.一家独大
计算机是由美国人发明的 为了能够让计算机识别英文
需要发明一个数字跟英文字母的对应关系
ASCII码:记录了英文字母跟数字的对应关系
用8bit(1字节)来表示一个英文字符
4.2.群雄割据
中国人
GBK码:记录了英文、中文与数字的对应关系
用至少16bit(2字节)来表示一个中文字符
很多生僻字还需要使用更多的字节
英文还是用8bit(1字节)来表示
日本人
shift_JIS码:记录了英文、日文与数字的对应关系
韩国人
Euc_kr码:记录了英文、韩文与数字的对应关系
"""
每个国家的计算机使用的都是自己定制的编码本
不同国家的文本数据无法直接交互 会出现"乱码"
"""
4.3.天下一统
unicode万国码
兼容所有国家语言字符
起步就是两个字节来表示字符
utf系列:utf8 utf16 ...
专门用于优化unocide存储问题
英文还是采用一个字节 中文三个字节
文件操作与诸多方法
-
文件操作
1.文件的概念 就是操作系统暴入给用户操作硬盘的快捷方式 比如双击一个文件 就是冲硬盘将数据加载到内存 ctrl+s保存文件 就是将内存的数据刷到硬盘保存 2.代码打开文件的两种方式 open关键字 第一种 # open打开文件填入文件路径,读写模式(r w a)选择 最后转进制 第二种: with open('a.txt', 'r', encoding= 'utf8') as f1: with子代码 #with上下文管理好处在于子代码运行结束自动调用close方法关闭资源 """ open方法的第一个参数是文件路径 并且撬棍跟一些字母的组合会产生特殊的含义导致路径查找混乱 为了解决该问题可以在字符串的路径前面加字母r D:\a\n\t r'D:\a\n\t' 以后涉及到路径的编写 推荐加上r with支持一次性打开多个文件 with open() as f1,open() as f2,open() as f3: 子代码 """
-
文件读写模式
分为三种模式 'r' 'w' 'a' 'r'只读模式: 只能读不能写,文件路径不存在会直接报错,文件路径存在就正常 读写内容 'w'只写模式: 只能写不能看,文件路径不存在自动创建,文件路径存在会先清空 然后在写入 '换行符需要自己加,做数据对比要注意' 'a'只追加模式 文件末尾追加数据,文件路径存在会自动创建,文件路径存在自动在末尾追加内容 '写代码的时候不知道写什么可以用pass代替' '只补全语法不执行任何功能,本身没有任何含义'
-
文本操作模式
# t 文本模式 默认的模式 r w a 全称其实是rt wb at 1.只能操作文本型文件,其他不行 2.读写都是以字符为单位的 3.需要指定encoding参数 如果不知道就会采用计算机默认编码 # b 二进制模式 也可以叫做bytes模式 1.不是默认的模式,需要自己指定rt wb at 2.可以操作任意类型的文件 3.读写都是bytes单位 4.不需要encoding参数 因为已经是二进制了,不需要编码了
-
文件的各种方法
1.read() 一次性读取文件内容 并且指示标停留在文件末尾 继续读取则没有内容 缺点是当文件内容较多的时候,此方法会造成计算机内存溢出 括号内可以填写数字 在文本模式下 表示读取几个字读 2.for循环 一行行读取文件 避免内存溢出现象发生 3.readline() 一次只读一行 4.readlines() 一次性读取文件内容 会按照行数组成列表的一个个数据值 5.readable() 判断文件是否具有读数据的能力 6.write() 写入数据 7.writeable() 判断文件是否有写数据能力 8.writelines 接受一个列表 一次性将列表所有数据值写入 9.flush() 将内存的文件立马刷到硬盘 等同于CTRL+s
-
文件内指示标移动方法
with open(r'a.txt', 'rb') as f: print(f.read()) f.seek(0,0) print(f.read()) f.seek(0, 0) print(f.read()) # print(f.read(2).decode('utf8')) # f.seek(-1, 2) # print(f.tell()) # 返回光标距离文件开头产生的字节数 """ seek(offset, whence) offset是位移量 以字节为单位 whence是模式 0 1 2 0是基于文件开头 文本和二进制模式都可以使用 1是基于当前位置 只有二进制模式可以使用 2是基于文件末尾 只有二进制模式可以使用 """ # print(f.read(3).decode('utf8'))
-
文件内容修改
### 方式一:覆盖写 将文件内容一次性全部读进内存,然后在内存中修改完毕在覆盖写回原文件 # with open(r'a.txt', 'r', encoding='utf8') as f: # data = f.read() # with open(r'a.txt', 'w', encoding='utf8') as f1: # f1.write(data.replace('jason', 'tony')) 1.以r模式打开源文件,将源文件内容全部读入内存 2.然后在内存中修改完毕 3.以w模式打开源文件,将修改后的内容写入源文件 ### 方式二:换地写 以读的方式打开原文件,以写的方式打开一个临时文件,一行一行读取原文件内容,修改完后写入临时文件,删掉原文件,将新文件重名名为原文件名 import os with open('a.txt', 'r', encoding='utf8') as read_f, \ open('.a.txt.swap', 'w', encoding='utf-8') as write_f: for line in read_f: write_f.write(line.replace('tony', 'kevinSB')) os.remove('a.txt') # 删除a.txt os.rename('.a.txt.swap', 'a.txt') # 重命名文件 1.以r模式打开源文件 然后以w模式打开临时文件 2.从源文件读取一行到内存中 修改完毕后直接写入临时文件 循环反复 知道完成所有行 3.删除源文件 将临时文件改成源文件名
计算机硬盘修改数据原理
1.硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
2.文件对应的是硬盘空间,硬盘不能修改对应着文件本质也不能修改, 那我们看到文件的内容可以修改, 大致的思路是将硬盘中文件内容 读入内存,然后在内存中修改完毕后再覆盖回硬盘
3.硬盘删除数据的原理
不是直接删除而是改变状态 等待后续数据的覆盖才会被真正删除
函数
def 函数名(参数):
'''函数注释'''
函数体代码
return 返回值
1.def
定义函数的关键字
2.函数名
命名等同于变量名
3.参数
主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释
大白话就是说明书
5.函数体代码
函数的核心 主要是取决于程序员的编写
6.return
使用函数之后可以返回给使用者的数据 可有可无
-
函数定义与调用
1.函数在定义阶段只检测语法 不执行代码 2.函数必须先定义后调用 3.函数在调用阶段才会执行函数体代码 4.函数定义使用关键字def """ Python函数是指组织好的、可重复使用的、用来实现单一或相关联功能的代码段,Python函数包含系统中自带的一些函数、第三方函数以及用户自定义的函数。 函数能提高应用的模块性和代码的重复利用率,你已经知道Python提供了许多内置函数,比如说print(),但你也可以自己创建函数,这被叫作用户自定义函数。 """
-
函数的的分类
1.空函数 函数体代码为空使用pass或者...补全 主要用于函数框架的构造,加上注释提醒自己 2.有参函数 定义函数的时候括号内有参数 调整函数的时候括号内传参 3.无参函数 定义函数的时候括号内没有参数
-
函数的返回值
1.什么是返回值 调用函数之后返回给调用者的结果 2.如何获取返回值 变量名 赋值符号 函数的调用 res = func() # 先执行func函数 然后将返回值赋值给变量res 3.函数返回值的多种情况 3.1.函数体代码中没有return关键字 默认返回None 3.2.函数体代码有return 如果后面没有写任何东西还是返回None 3.3.函数体代码有return 后面写什么就返回什么 3.4.函数体代码有return并且后面有多个数据值 则自动组织成元组返回 3.5.函数体代码遇到return会立刻结束 # 类似于black
-
函数的参数
1.形参 定义阶段填写的参数 2.实参 调用阶段填写的参数
-
位置参数
位置形参 函数定义阶段括号内从左往右依次填写变量名 def func1(a, b, c):pass 位置实参 函数调用阶段依次从左往右填写的数据值 func1(1, 2, 3) 代码案例理解: def func1(a, b): print(a,b) func1(1, 2) # 1,2 按照位置从左到右一一对应传值 func1(1) # 必须都要有对应的值,少一个不行,直接报错 func1(1, 2, 3) # 多一个也不行,直接报错 func1(a=1, b=2) # 可以指名道姓的传 a传1 b传2 func1(b=1, 2) # 关键字传参一定要跟在位置传参后面 报错 func1(2, b=1) # 这是可以的因为他跟着位置传参后面 func1(1, a=2, b=3) # 同一个参数在调用的情况下不能多次赋值 直接报错 # 上述1已经赋值给a了 然后2又赋值给a这是不可以的 name = 'jason' pwd = 123 # func1(name, pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名 func1(a=name, b=pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名 越短越简单的靠前越长越复杂的靠后
-
默认参数
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数 def register(name, age, sex='male'): # 默认sex为male print(''' ```````学生信息````````` 姓名:{name} 年龄:{age} 性别:{sex} ''') register('jason', 18) register('kevin', 28) register('lili', 28, 'female') register('lili', 28, sex='female') # 性别会自动显示male 可以手动修改
-
可变长形参
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数 def func1(*a): print(a) func1() # () func1(1) # (1,) func1(1,2) # (1, 2) def func2(b, *a): print(a, b) func2() # 函数至少需要一个参数给b func2(1) # () 1 func2(1, 2, 3, 4) # 实参1按照位置给b赋值 多余的234则被*号吸收然后以元组的形式保存赋值给a ''' *号在实参中用于接收多余的位置参数,然后组成元组赋值给*号后面的变量名 ''' def func3(**k): print(k) func3() # {} 字典形式 func3(a=1) # {'a': 1} func3(a=1,b=2,c=3) # {'a' : 1, 'b' : 2, 'c' : 3} def func4(a, **k): print(a, k) func4() # 函数至少需要一个参数给到a func4(a=1) # 1 {} func4(a=1, b=2, c=3) # 1 {'b': 2, 'c': 3} func4(a=1, b=2, c=3, x='jason', y='kevin') # 1 {'b': 2, 'c': 3, 'x': 'jason', 'y': 'kevin'} # 应关键字参数1 然后多余的被**吸收转成字典的形式赋值给**后面的变量名 def func5(n, *a, **k): print(n, a, k) func5(1, 2, 3) # 1 (2, 3) {} 1赋值给n 2和3赋值给a并且转成元组 代码中没有关键字参数所以为空 func5(n=1, a=2, c=3) # 1 () {'a': 2, 'c': 3} # 1赋值给n a没有适合自己的赋值为空 剩下的ac关键字参数转成字典赋值给k func5(1, 2, 3, a=1, b=2, c=3) # 1 (2, 3) {'a': 1, 'b': 2, 'c': 3} # 1赋值给n 23转元组赋值给a 剩下的是关键字参数全部转字典赋值给k ''' 由于*和**在函数的形参中使用频率很高 后面跟的变量名推荐使用 *args **kwargs def index(*args,**kwargs):pass """
-
可变长实参
def index(a, b, c): print(a, b, c) l1 = [11, 22, 33] t1 = (33, 22, 11) s1 = 'jon' se = {123, 321, 222} d1 = {'username': 'jason', 'pwd': 123, 'age': 18} index(*l1) # 11 22 33 把列表拿走了传出里面的数据值 index(*t1) # 33 22 11 把元组拿走了传出数据值 index(*s1) # j o n jon 拆开一一对应abc index(*se) # 321 123 222 字典去掉,一一对应abc 但是是无序排列 index(*d1) # username pwd age 只会取键对应abc """ *在实参中 类似于for循环 将所有循环遍历出来的数据按照位置参数一次性传给函数 """ def index(username, pwd, age): print(username, pwd, age) d1 = {'username': 'jason', 'pwd': 123, 'age': 18} index(**d1) # index(username='jason',pwd=123,age=18) # 取键值 对应username pwd age """ **在实参中 将字典打散成关键字参数的形式传递给函数 """ def index(*args, **kwargs): print(args) # (11, 22, 33, 44) print(kwargs) # {} index(*[11, 22, 33, 44]) # index(11, 22, 33, 44) # 多余的位置参数被*号吸收转成元组
-
函数名的多种用法
函数名其实绑定的也是一块内存地址 只不过该地址里面存放的不是数据值而是一段代码 函数名加括号就可以找到改代码运行 1.可以当作变量名赋值 def index():pass res = index res() 2.可以当作函数参数 def index(): print('from index') def func(a): print(a) a() 3.可以当作函数的返回值 def index(): print('from index') def func(): print('from fucn') return index res = func() print(res) res() def index(): print('from index') def func(): print('form func') return func res = index() print(res) res() 4.可以存放多个数据类型的数据 # 简单写两个 def register(): print('注册功能') def login(): print('登录功能') ## 定义功能便号与功能对应关系 func_dict = { '1':register '2':login } while True: print(""" 1.注册功能 2.登入功能 """) choice = input('请输入>>>:').strip() if choicen in func_dict: func_name = func_dict.get(choice) func_name() else: print('编号不存在')
-
闭包函数
定义在函数内部的函数 并且用到了外部函数名称空间的名字 1.定义在函数的内容 2.用到外部函数名称空间中的名字 def index(): name = 'jason' def inner(): print(name) '闭包函数的实际应用实际上就是另一种给函数体代码的传参方式!!!' # 给函数体代码传参的方式1: def register(name,age, gender): print(f""" 姓名:{name} 年龄:{age} 性别:{gender} """) register('jason', 18, male) # 给函数体代码传参方式2:闭包函数 def outer(name, age): def register(): print(f""" 姓名:{name} 年龄:{age} """) return register res = outer('jason', 18) res() res = outer('shabi', 28) # 更改 res()
-
递归函数
1.函数的递归调用 函数直接或者间接的调用了函数自身 # 直接调用 def index(): # 1写一个函数 print('from index') # 3 index() # 又返回函数index一直反复 index() # 2 # 间接 def index(): # 1函数 print('from index') # 6 func() # 7 又回到func def func(): # 2函数 print('from func') # 4 index() # 5.又回到index func() # 3 '''最大递归深度:python解释器添加的安全措施''' count = 0 def index(): global count count += 1 print(count) index() index() #官网提供的最大递归深度为1000 2.递归函数 直接或者间接的调用自己 每次调用都比上一次简单,并且需要有一个明确的结束条件 递推 一层层往下 回溯 基于明确结果一层层往上 """ get_age(5) = get_age(4) + 2 get_age(4) = get_age(3) + 2 get_age(3) = get_age(2) + 2 get_age(2) = get_age(1) + 2 get_age(1) = 18 """ def get_age(n): # 函数 if n == 1: return 18 # 明确结果18 return get_age(n-1) + 2 # 刚开始时n-1+2一层层往上 res = get_age(5) # n就是get_age(5) print(res)
global与nonlocalx
money = 666 # 1.命名赋值
def index(): # 2.看到命名函数先找命名函数
global money # 4.使用global局部修改全局数据
money = 123 # 5.修改后的数据
index() #3.执行函数体代码
print(money) # 6.打印123
"""局部空间修改全局空间数据"""
def index(): # 1.看到函数 index直接不用看别的 找对应的
name = 'shabi' # 3.第三步执行位置
def inner(): # 4.从上往下执行又到函数
nonlocal name # 6. 使用nonlocal做出修改
name = 'naocan' # 7. 修改完毕
inner() # 5.第四步对应位置
print(name) # 8. 打印naocan
index() # 2.运行函数体代码
"""部局部空间修改外层局部空间数据"""
名称空间
名称空间就是储存变量名的地方
1.内置名称空间
# python解释器当中的名字
2.全局名称空间
# 运行python文件产生的空间
3.局部名称空间
# 运行函数产生的空间
-
名称空间存活周期及作用域
# 存活周期 内置名称空间 python解释器启动创建 关闭销毁 全局名称空间 python文件执行创建 运行结束销毁 局部名称空间 函数体代码运行创建 结束销毁 # 作用域 内置名称空间 解释器级别的全局有效 全局名称空间 py文件级别的全局有效 局部名称空间 函数体代码内有效
-
名字查找顺序
名字的查找一定要先清除自己在哪个空间 1.当我们在局部空间的时候 局部>>全局>>内置 2.当我们在全局空间的时候 全局>>内置 可以从里到外,不能从外到里 名字的查找顺序可以打破 '函数在定义阶段查找顺序就已经定死了'
装饰器
-
简介
1.概念: 在不改变装饰对象源代码喝调用方式的情况下给装饰对象添加新功能 2.本质: 并不是新的技术 而是由函数参数 名称空间 函数名多种用法,闭包函数组合到一起的结果 3.口诀 对修改封闭 对扩展开放 4.储备知识 时间相关操作 import time print(time.time()) # 时间戳(距离1970-01-01 00:00:00所经历的秒数) time.sleep(3) # 间隔三秒打印 print('你真是个星星星') count = 0 # 循环获取之前的时间戳 start_time = time.time() while count < 100: print('xixixi') count += 1 end_time = time.time() print('循环消耗时间:', end_time - start_time)
-
装饰器推到流程
import time def index(): time.sleep(3) print('from index') # from index def home(): time.sleep(1) print('from home') # from home '''1.直接在调用index函数的前后添加代码''' start_time = time.time() index() end_time = time.time() print('函数index的执行时间为>>>:', end_time-start_time) '''2.index调用的方法较多 代码不可能反复拷贝>>>:相同的代码需要在不同的位置反复执行>>>:函数''' def get_time(): start_time = time.time() index() end_time = time.time() print('函数index的实行时间为>>>:', end_time-start_time) get_time() """3.函数体代码写死了 只能统计index的执行时间 如何做到统计更多函数运行时间 可以直接传参变换统计的函数 """ def get_time(xxx): start_time = time.time() xxx() end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) get_time(index) get_time(home) '''4.虽然实现了一定的兼容性 但是并不符合装饰器的特征 第一种传参不写 只能考虑闭包''' def outer(xxx): # xxx = index def get_time(): start_time = time.time() xxx() end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) return get_time res = outer(index) res() res1 = outer(home) res1() '''5.调用方式还是不对 如何变形>>>:变量名赋值绑定 (******)''' def outer(xxx): def get_time(): start_time = time.time() xxx() end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) return get_time res = outer(index) # 赋值符号的左边是一个变量名 可以随意命名 res1 = outer(index) res2 = outer(index) jason = outer(index) index = outer(index) index() home = outer(home) home() '''6.上述装饰器只能装饰无参函数 兼容性太差''' def func(a): time.sleep(0.1) print('from func', a) def func1(a,b): time.sleep(0.2) print('from func1', a, b) def func2(): time.sleep(0.3) print('from func2') func(123) def outer(xxx): def get_time(a, b): start_time = time.time() xxx(a, b) end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) return get_time func1 = outer(func1) func1(1, 2) func = outer(func) func(1) func2 = outer(func2) func2() '''7.被装饰的函数不知道有没有参数以及有几个参数 如何兼容''' def func(a): time.sleep(0.1) print('from func', a) def func1(a,b): time.sleep(0.2) print('from func1', a, b) def outer(xxx): def get_time(*args, **kwargs): # get_time(1,2,3) args=(1,2,3) start_time = time.time() xxx(*args, **kwargs) # xxx(*(1,2,3)) xxx(1,2,3) end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) return get_time func = outer(func) func(123) func1 = outer(func1) func1(1, 2) '''8.如果被装饰的函数有返回值''' def func(a): time.sleep(0.1) print('from func', a) return 'func' def func1(a,b): time.sleep(0.2) print('from func1', a, b) return 'func1' def outer(xxx): def get_time(*args, **kwargs): start_time = time.time() res = xxx(*args, **kwargs) end_time = time.time() print('函数的执行时间为>>>:', end_time - start_time) return res return get_time func = outer(func) res = func(123) print(res) func1 = outer(func1) res = func1(123, 123) print(res)
-
装饰器模板
# 常用无参装饰器 def outter(func): def inner(*args, **kwargs): res = func(*args, **kwargs) return res return inner # 不常用有参装饰器 def outer_plus(mode): def outer(func_name): def inner(*args, **kwargs): res = func_name(*args, **kwargs) return res return inner return outer @outer_plus('MySQL') def func(): pass
-
装饰器语法糖
每次转换的语句func = outer(func)比较麻烦,而且实际写代码时由于位置不固定也十分的乱。 python提供了一个简单语法,来代替这一条语句: @outer # 紧贴着要被装饰的函数前,代表func = outer(func) def func(): """被装饰函数""" pass
-
多层语法糖
def outter1(func1): # 1先看函数 print('加载了outter1') def wrapper1(*args, **kwargs): print('执行力wrapper1') res1 = func1(*args, **kwargs) return res1 return wrapper1 def outer2(func2): # 2 print('加载了outter2') def wrapper2(*args, *kwargs): print('执行了warpper2') res2 = func2(*args, **kwargs) return res2 return wrapper2 def outer3(func3): # 3 print('加载了outter3') def wrapper3(*args, **kwargs): print('执行了warpper3') res3 = func3(*args, *kwargs) return res3 return wrapper3 @outer1 # index = outer1(加载了outer3的index即wrapper2)>>>wrapper1——>index @outer2 # outer2(加载了outer3的index即wrapper3)>>>wrapper2 @outer3 # outer3(原本的index)>>>wrapper3 def index(): # 4 print('form index') index() """多层语法糖 加载顺序由上往下 每次执行了之后如果上面还有语法糖 就直接将返回函数名传给上面的语法糖 如果上面没有语法糖了 就变形 index = outter(wrapper) """
-
装饰器修复技术(了解)
# def index(): # """index函数 非常的牛""" # pass # help(index) # help(len) from functools import wraps def outer(func_name): @wraps(func_name) # 仅仅是为了让装饰器的效果更加逼真 平时可以不写 def inner(*args, **kwargs): """我是inner 我擅长让人蒙蔽""" res = func_name(*args, **kwargs) return res return inner @outer def func(): """我是真正的func""" pass # help(func) # print(func) func()
二分法
1.什么是算法
算法就是解决问题的有效方法 不是所有算法都很高效也有不合格的算法
2.算法应用场景
推荐算法:比如抖音
成像算法:AI相关
几乎覆盖了生活的方方面面
3.二分法
是算法中最简单的算法 甚至称不上算法
"""
二分法的使用要求
要查找的数据集必须时有序的
二分法的缺陷
针对开头结尾的数据查找效率很低
常见算法的原理以及伪代码
二分法 冒泡 快拍 插入 堆排 桶排 数据结构(链表 约瑟夫问题 如何链表是否成坏)
"""
查找算法:
1.for循环遍历一次就可以解决
比如说有一个列表l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
for num in l1: # 逐一遍历
if num == 123:
print('找到了')
break
else:
print('没找到')我想找到123
2.二分法:
def get_midd(l1, target_num):
if len(l1) == 0:
print('抱歉没找到')
return
midd_index = len(l1) # 获取列表索引值
if target_num > l1[midd_index]: # 比索引中间大小
right_l1 = l1[midd_index + 1:] # 切片保留右半边
print(right_l1)
return get_midd(right_l1, target_num)
elif target_num < l1[:midd_index]: # 保留另一半
left_l1 = l1[:midd_index]
print(left_l1) # 针对左边另一半继续二分
return get_midd(left_l1, target_num)
else:
print('找到了')
# get_middle(l1, 987)
# get_middle(l1, 2000)
# get_middle(l1, 12)
三元表达式
简化步骤1: 代码简单只有一行直接冒号后写
name = 'linux'
if name == 'linux':
print('老师')
else:
print('学生')
三元表达式 # 看的非常的简洁
res = '老师' if name == 'linux' else '学生'
print(res)
"""
数据值1 if 条件 else 数据值2
条件成立则使用数据值1 条件不成立则使用数据值2
当结果是二选一的情况下 使用三元表达式较为简便
并且不推荐多个三元表达式嵌套
"""
匿名函数
没有名字的函数 需要使用关键字# lambda
语法结构
lambda 形参:返回值
使用场景
lambda a,b:a+b
匿名函数一般不单独使用 需要配合其他函数一起用
内置函数
-
常见
1.abs() # 一种求数据绝对值的函数
# print(abs(-100)) # print(abs(100))
2.all() # 所有数据值对应的布尔值为True结果才是True 否则返回False
# print(all([0, 1, 2, 3])) # print(all([1, 2, 3, True]))
3.any() 所有数据值对应的布尔值有一个为True结果就是True 否则返回False
# print(any([0, None, '', 1])) # print(any([0, None, '']))
4.bin() 返回一个整数 int 或者长整数 long int 的二进制表示。
>>>bin(10) '0b1010' >>> bin(20) '0b10100'
5.oct() 函数将一个整数转换成 8 进制字符串。
>>> oct(10) '0o12' >>> oct(20) '0o24' >>> oct(15) '0o17'
6.hex() 函数用于将10进制整数转换成16进制,以字符串形式表示
>>>hex(255) '0xff' >>> hex(-42) '-0x2a' >>> hex(1L) '0x1L' >>> hex(12) '0xc' >>> type(hex(12)) <class 'str'> # 字符串
7.int() 函数用于将一个字符串或数字转换为整型
>>>int() # 不传入参数时,得到结果0 0 >>> int(3) 3 >>> int(3.6) 3 >>> int('12',16) # 如果是带参数base的话,12要以字符串的形式进行输入,12 为 16进制 18 >>> int('0xa',16) 10
8.bytes()
转换成bytes类型
9.callable()
函数用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功 对于函数、方法、lambda 函式、 类以及实现了 **__call__** 方法的类实例, 它都返回 True callable()方法语法: callable(object)
10.chr() ord()
chr(i) 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符 返回值是当前整数对应的AScll字符 i -- 可以是10进制也可以是16进制的形式的数字 >>>print chr(0x30), chr(0x31), chr(0x61) # 十六进制 0 1 a >>> print chr(48), chr(49), chr(97) # 十进制 0 1 a ord() 返回对应的 ASCII 数值 >>>ord('a') 97 >>> ord('b') 98 >>> ord('c') 99
11.dir()
函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
dir(对象,变量,类型) 返回值是返回模块的属性列表 例: >>>dir() # 获得当前模块的属性列表 ['__builtins__', '__doc__', '__name__', '__package__', 'arr', 'myslice'] >>> dir([ ]) # 查看列表的方法
12.divmod()
函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组
语法: divmod(数字, 数字) 例: >>>divmod(7, 2) (3, 1) >>> divmod(8, 2) (4, 0) >>> divmod(1+2j,1+0.5j) ((1+0j), 1.5j)
13.enumerate()
枚举
14.eval() exec()
eval() 函数用来执行一个字符串表达式,并返回表达式的值 返回值:是返回表达式计算结构 语法: eval(expression[, globals[, locals]]) expression -- 表达式 globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象 locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对像 例: >>>x = 7 >>> eval( '3 * x' ) 21 >>> eval('pow(2,2)') 4 >>> eval('2 + 2') 4 >>> n=81 >>> eval("n + 4") 85
15.hash()
用于获取取一个对象(字符串或者数值等)的哈希值
16.id()
函数返回对象的唯一标识符,标识符是一个整数 CPython 中 id() 函数用于获取对象的内存地址
17.map() 映射
会根据提供的函数对指定序列做映射 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表 l1 = [1, 2, 3, 4, 5] # def func(a): # return a + 1 res = map(lambda x:x+1, l1) #使用匿名函数 print(list(res))
18.max()
方法返回给定参数的最大值,参数可以为序列。
19.min()
方法返回给定参数的最小值,参数可以为序列
20.open()
打开一个文件
21.pow()
方法返回 xy(x 的 y 次方) 的值。
22.range()
返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表
23.round()
方法返回浮点数x的四舍五入值。 但是有一种情况如果是5还是会丢弃是6才会进 简单可以理解为五舍六入
24.sum()
方法对序列进行求和计算。
25.zip()
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表
-
重要内置函数
1.zip #拉链 可以对多个数据合并 并且组成一个元组 如果数据多了则会被丢弃 # 代码举例: # l1 = [11, 22, 33, 44, 55] # l2 = ['jason', 'kevin', 'oscar', 'jerry', 'tony'] # l3 = [1, 2, 3, 4, 5] # res = zip(l1, l2, l3) # print(list(res)) 2.filter #可以基于定义的条件筛选一系列数据 # l1 = [11, 22, 33, 44, 55, 66, 77, 88] # res = filter(lambda x: x > 40, l1) # print(list(res)) 3.sorted 对数据进行排序 默认是升序 l1 = [21, 12, 53, 64, 76, 32, 11, 22] res = sorted(l1) print(res)
可迭代对象
1.可迭代对象
对象内置有__iter__方法的都称为可迭代对象
"""
1.内置方法 通过点的方式能够调用的方法
2.__iter__ 双下iter方法
"""
2.可迭代对象的范围
不是可迭代对象
int float bool 函数对象
是可迭代对象
str list dict tuple set 文件对象
3.可迭代的含义
"""
迭代:更新换代(每次更新都必须依赖上一次的结果)
"""
在上上数据类型中我们可以发现可迭代兑现都是支持for循环的
迭代对象器
1.迭代器对象
是由可迭代对象调用__iter__方法产生的
迭代器对象判断的本质是看是否内置有__iter__和__next__
2.迭代器对象的作用
提供了一种不依赖于索引取值的方式
正因为有迭代器的存在 我们的字典 集合才能够被for循环
3.迭代器对象实操
s1 = 'hello' # 可迭代对象
res = s1.__iter__() # 迭代器对象
print(res.__next__()) # 迭代取值 for循环的本质
一旦__next__取不到值 会直接报错
4.注意事项
可迭代对象调用__iter__会成为迭代器对象 迭代器对象如果还调用__iter__不会有任何变化 还是迭代器对象本身
for循环的本质
for 变量名 in 可迭代对象:
循环体代码
"""
1.先将in后面的数据调用__iter__转变成迭代器对象
2.依次让迭代器对象调用__next__取值
3.一旦__next__取不到值报错 for循环会自动捕获并处理
"""
异常捕获/处理
1.异常
异常就是代码运行报错 行业俗语叫bug
代码运行中一旦遇到异常会直接结束整个程序的运行 我们在编写代码的过程中药尽可能避免
2.异常分类
语法错误
不允许出现 一旦出现立刻改正 否则提桶跑路
逻辑错误
允许出现的 因为它一眼发现不了 代码运行之后才可能会出现
3.异常结构
错误位置
错误类型
错误详情
标签:总结,index,函数,本周,func,time,print,def
From: https://www.cnblogs.com/lsl1/p/16796898.html