装饰器生成式迭代器
Posted syy1757528181
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器生成式迭代器相关的知识,希望对你有一定的参考价值。
def my_sum(x,y):
return x+y
res = my_sum(1,2)
print(res)
函数对象
#函数名是第一类对象:
函数名指向的值可以被当作参数传递(类似于变量)
name = ‘syy‘
x = name
print(x) #syy
print(id(x)) #2553483145936
def func():
pass
print(func) #<function func at 0x0000025287641EA0>
print(func()) #None
print(id(func())) #1904845968
#函数名可以被当做参数传递给其他函数
#可以在定义之后的任何位置调用(包括函数体内部)
def func():
print(‘from func‘)
print(func)
def index(args):
print(args)
print(‘from index‘)
index(func)
#函数名可以被当做函数的返回值,该功能实现了全局访问局部
def func():
print(‘from func‘)
def index():
print(‘from index‘)
return func()
res = index()
print(res)
from index
from func
None
#函数名可以被当做容器类型的元素
def func():
print(‘from func‘)
print(func())
l = [1,2,func,func()]
print(l)
from func
None
from func
[1, 2, <function func at 0x000001C9A5581EA0>, None]
#callable 可调用的,也就是说可以加括号(),执行某一功能
#网络爬虫,就是爬取一个网页的源代码
1.在终端安装Terminal
pip3 install requests
2.使用pycharm安装(file-settings-project: project interpreter-双击)
import requests
response = requests.get(‘https://www.baidu.com‘)
if response.status_code == 200:
print(response.text)
函数的嵌套调用与嵌套定义
#函数的嵌套:
在函数内部调用其他函数
可以将复杂的问题简单化
#先定义,后调用(相对于同级来说)
def index():
func()
print(‘index‘)
def func():
print(‘func‘)
func()
#嵌套调用返回值的问题,全局访问局部
def outer():
print(‘outer‘)
def inner():
print(‘inner‘)
return inner
res = outer()
print(res)
print(res())
#函数嵌套的应用场景
def my_max_2(x,y):
if x > y:
return x
return y
def my_max_4(a,b,c,d):
res1 = my_max_2(a,b)
res2 = my_max_2(res1,c)
res3 = my_max_2(res2,d)
return res3
print(my_max_4(1,4,8,999))
#函数复杂的功能与简单的接口
def all_func(type):
if type == ‘1‘:
print(‘redister‘)
elif type == ‘2‘:
print(‘login‘)
elif type == ‘3‘:
print(‘shopping‘)
all_func(‘1‘)
名称空间
#什么是名称空间
存放变量名与变量值的内存地址的绑定关系的地方
#变量名与变量值
想要访问一个变量的值,必须先去名称空间中拿到变量名,才能访问到内存中的变量的值
#名称空间的分类
1.内置名称空间
python解释器‘提前定义好‘的变量名、函数名,放到内置名称空间
len()、max()、min()
2.全局名称空间
‘文件级别‘的
if、for、while无论嵌套多少层,他们内部所创建的变量名、函数名,都放到全局名称空间
3.局部名称空间
‘函数体内创建‘的变量名、函数名,都放到局部名称空间
局部名称空间之间无法直接访问
#生命周期
内置名称空间,只要python解释器启动,就会立刻创建,关闭python解释器的话,内置名称空间自动销毁
全局名称空间,只要右键运行`.py`文件,自动创建,`.py`文件程序运行结束,自动销毁
局部名称空间,函数被调用的时候自动创建,函数指向结束,自动销毁
#名称空间的访问顺序
#所在位置为全局的时候,调用函数名的话,先去全局名称空间找,再去局部名称空间中找
len = ‘我是全局名称空间中的len‘
def func():
len = ‘我是局部名称空间中的len‘
print(len)
print(len)
#所在位置为局部的时候,调用函数名的话,先去局部名称空间找,再去全局名称空间找,再去内置名称空间找
len = ‘我是全局名称空间中的len‘
def func():
len = ‘我是局部名称空间中的len‘
print(len)
func()
#同级别局部名称空间不能互相访问
def index():
x = 1
# print(y)
def func():
# print(x)
y = 666
index()
func()
#下级名称空间可以访问上级名称空间,上级名称空间不能访问下级名称空间
x = 2
def index():
x = 1
def func():
print(x)
return func
x = 3
res = index()
res()
#函数在定义阶段,查找名字的顺序就已经固定了,不会因为函数的调用位置的变化而变化
x = 2
def index():
x = 1
def func():
print(x)
return func
x = 3
res = index()
x = 4
res() #1
x =5
def f1():
x = 1
def f2():
x = 2
def f3():
x = 3
def f4():
x = 4
print(x)
f4()
f3()
f2()
res = f1() #4,print()函数打印出来的
print(res) #None,没有return,所以函数返回值为None
x = 1
def outer():
def inner():
print(‘from inner‘,x)
return inner
res = outer()
def func():
x = 2
res()
func() #from inner 1
x = 1
def outer():
def inner():
print(‘from inner‘,x)
# x = 2 ,变量x在函数inner内部找,但是应该在调用之前定义
return inner
res = outer()
res() #报错
名称空间与作用域
#全局作用域
内置名称空间、全局名称空间都是全局作用域,都是全局有效
#局部作用域
局部名称空间都是局部作用域,局部有效
#名称空间的作用顺序
x = 1
def func():
x = 2
func()
print(x) #1
#当全局是可变数据类型,直接可以局部修改全局
x = []
def func():
x.append(‘哈哈哈‘)
func()
print(x)
#关键字 global,作用于全局是不可变数据类型,在全局名称空间创建变量,global声明多个的时候使用逗号隔开
x = 1
def func():
global x
x = 2
func()
print(x)
#关键字 nonlocal,作用于下一级对上一级局部名称空间内变量的修改
def func():
x = 1
def index():
x = 2
index()
print(x)
func() #1
def func():
x = 1
def index():
nonlocal x
x = 2
index()
print(x)
func() #2
购物车
msg = """
1.注册
2.登录
3.转账
4.购物
5.支付
"""
def register():
print(‘register...‘)
def login():
print(‘login...‘)
def transfer():
print(‘transfer...‘)
def shopping():
print(‘shopping...‘)
def pay():
print(‘pay...‘)
func_dict = {
‘1‘:register,
‘2‘:login,
‘3‘:transfer,
‘4‘:shopping,
‘5‘:pay,
}
while True:
print(msg)
choise = input(‘请输入你想要执行的功能>>>: ‘).strip()
if choise in func_dict:
func_dict.get(choise)() #执行函数
else:
print(‘相关功能还在开发中...‘)
# if choise == ‘1‘:
# db_username = input(‘请输入你的用户名>>>: ‘).strip()
# db_passwd = input(‘请输入你的密码>>>: ‘).strip()
# print(‘用户注册成功‘)
# elif choise == ‘2‘:
# username = input(‘请输入你的用户名>>>: ‘).strip()
# passwd = input(‘请输入你的密码>>>: ‘).strip()
# elif choise ==‘3‘:
# transfer()
# elif choise ==‘4‘:
# shopping()
# elif choise == ‘5‘:
# pay()
闭包函数
#闭:定义在函数内部的函数
#包:内部函数引用了外部函数作用域的变量名、函数名
#格式
y = 2
def outer():
x = 1
def inner():
print(x,y)
#闭包函数访问内部函数的问题
def outer():
x = 1
def inner():
print(x)
return inner
res = outer()
res() #1
#通过传参的方式,可以实现全局修改局部,使用关键字global、nonlocal可以实现局部修改全局
#给函数体传参的方式一 -- 位置参数传参
def index(username):
print(username)
#给函数体传参的方式二 -- 闭包函数
#闭包函数不会浪费变量名
def outer():
x = 1
y = 10
def my_max():
if x > y:
print(x)
print(y)
return my_max
res = outer()
res() #10
def outer(x,y):
def my_max():
if x > y:
print(x)
print(y)
return my_max
res = outer(1,10)
res() #10
#闭包函数与网络爬虫(使用闭包函数,定义变量名)
import requests
def my_req(url):
def inner():
response = requests.get(url)
if response.status_code == 200:
print(response.text)
return inner
requests_baidu = my_req(‘https://www.baidu.com‘)
requests_baidu()
装饰器
#装饰器
装饰:就是给装饰对象添加新的功能
器: 就是一个工具
#装饰器原则:
开放:对扩展开放
封闭:对修改封闭(尽量不修改代码)
#装饰器条件:
1.不改变装饰对象的源代码
2.不改变被装饰对象(可调用对象callable)的调用方式 -- 使用闭包函数
#装饰器作用于可调用对象,还可以作用于装饰器
时间戳 (装饰器的原理)
#时间戳,当前时间距离1970-1-1 00:00:00相差的秒数
#1970-1-1 00:00:00为Unix的诞生元年
import time
print(time.time()) #1604630670.6970603
#CPU睡一觉
import time
print(‘I am syy‘)
time.sleep(3) #暂停3秒
print(‘GWY warning!‘)
#计算代码的执行时间
import time
def my_time():
print(‘syy‘)
time.sleep(3)
start = time.time()
my_time()
end = time.time()
print(‘%s 的执行时间是: %s‘%(‘函数my_time‘,end - start))
无参装饰器
#使用闭包函数修改函数名
import time
def func(): #测试函数
time.sleep(1)
print(‘重金求子‘)
def index(args):
def get_time():
start = time.time()
args()
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return get_time #返回值,返回被测试函数的返回值
func = index(func) #装饰器中的get_time函数名 = 装饰器名(要装饰的函数名)
func()
重金求子
执行时间是: 1.0055692195892334
装饰器的升级版
import time
def func():
time.sleep(1)
print(‘重金求子‘)
return ‘我是func‘
def login(name):
time.sleep(2)
print(‘%s login success‘%name)
return ‘我是login‘
def index(ch):
def get_time(*args,**kwargs):
start = time.time()
res = ch(*args,**kwargs)
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return res
return get_time
func = index(func) #装饰不需要传参的函数
res = func()
print(res)
login = index(login) #装饰需要传参的函数
res = login(‘syy‘)
print(res)
装饰器语法糖
import time
def index(ch):
def get_time(*args,**kwargs):
start = time.time()
res = ch(*args,**kwargs)
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return res
return get_time
@index #将下面紧挨着的函数的函数名,当做参数传入装饰器
def func():
time.sleep(1)
print(‘重金求子‘)
return ‘我是func‘
@index
def login(name): #@index,相当于login = index(login)
time.sleep(2)
print(‘%s login success‘%name)
return ‘我是login‘
res = func()
print(res)
res = login(‘syy‘)
print(res)
装饰器模板
#无参装饰器
from functools import wraps
def outter(func):
@wraps(func)
def inner(*args,**kwargs): #*在形参中使用(),{}
print(‘执行被装饰函数之前,可以进行的操作‘)
res = func(*args,**kwargs) #*在实参中使用(),{}
print(‘执行被装饰函数之后,可以进行的操作‘)
return res
return inner
@outter #装饰器中的inner函数名 = 装饰器名(要装饰的函数名)
def test():
pass
res = test()
print(res())
#有参装饰器
from functools import wraps
def wps(params1,params2):
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
print(‘执行被装饰函数之前,可以进行的操作‘)
res = func(*args,**kwargs)
print(‘执行被装饰函数之后,可以进行的操作‘)
return res
return inner
return outter
认证装饰器
#要求
1.执行函数index之前,必须先输入用户名和密码,认证之后才能执行index
2.否则提示用户输入错误,结束程序
def outter(func):
dict = {‘is_auto‘:None}
def inner(*args,**kwargs):
db_username = ‘syy‘
db_password = 123
if dict[‘is_auto‘]: #避免多次调用装饰器,需要重复登录的情况
res = func(*args, **kwargs)
return res
else:
username = input(‘请输入你的用户名>>>: ‘).strip()
password = int(input(‘请输入你的用户密码>>>: ‘).strip())
if username == db_username and password == db_password:
dict[‘is_auto‘] = True
res = func(*args,**kwargs)
return res
else:
print(‘用户名或密码输入错误!‘)
return inner
@outter
def index():
print(‘我是index函数‘)
res = index()
print(res)
@outter
def index2():
print(‘我是index2函数‘)
res = index2()
print(res)
多层装饰器
#多层装饰器在装饰的时候,顺序是从上往下
import time
def index(args):
def get_time():
start = time.time()
args()
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return get_time
def outter(func):
dict = {‘is_auto‘: None}
def inner(*args,**kwargs):
db_username = ‘syy‘
db_password = 123
if dict[‘is_auto‘]:
res = func(*args, **kwargs)
return res
else:
username = input(‘请输入你的用户名>>>: ‘).strip()
password = int(input(‘请输入你的用户密码>>>: ‘).strip())
if username == db_username and password == db_password:
dict[‘is_auto‘] = True
res = func(*args,**kwargs)
return res
else:
print(‘用户名或密码输入错误!‘)
return inner
@outter
@index
def index():
time.sleep(1)
print(‘我是index函数‘)
res = index()
print(res)
请输入你的用户名>>>: syy
请输入你的用户密码>>>: 123
我是index函数
执行时间是: 1.0005483627319336
None
测试
import time
def index(args):
def get_time():
start = time.time()
args()
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return get_time
def outter(func):
dict = {‘is_auto‘: None}
data_source = input(‘请输入你的密码存储类型(file/mysql/redis)>>>: ‘)
def inner(*args,**kwargs):
db_username = ‘syy‘
db_password = 123
if dict[‘is_auto‘]: #------------------------
res = func(*args, **kwargs)
return res
else:
if data_source == ‘file‘:
username = input(‘请输入你的用户名>>>: ‘).strip()
password = int(input(‘请输入你的用户密码>>>: ‘).strip())
if username == db_username and password == db_password:
dict[‘is_auto‘] = True
res = func(*args,**kwargs)
return res
else:
print(‘用户名或密码输入错误!‘)
elif data_source == ‘mysql‘:
print(‘mysql‘)
elif data_source == ‘redis‘:
print(‘redis‘)
else:
print(‘密码存储类型输入错误‘) #--------------------------
return inner
@outter
@index
def index():
time.sleep(1)
print(‘我是index函数‘)
res = index()
print(res)
有参装饰器(3层def)
import time
def index(args):
def get_time():
start = time.time()
args()
end = time.time()
print(‘执行时间是: %s‘%(end - start))
return get_time
def login_auth(data_source): #这一层仅仅是为了传参
def outter(func):
dict = {‘is_auto‘: None}
def inner(*args,**kwargs):
db_username = ‘syy‘
db_password = 123
if dict[‘is_auto‘]:
res = func(*args, **kwargs)
return res
else:
if data_source == ‘file‘:
username = input(‘请输入你的用户名>>>: ‘).strip()
password = int(input(‘请输入你的用户密码>>>: ‘).strip())
if username == db_username and password == db_password:
dict[‘is_auto‘] = True
res = func(*args,**kwargs)
return res
else:
print(‘用户名或密码输入错误!‘)
elif data_source == ‘mysql‘:
print(‘mysql‘)
elif data_source == ‘redis‘:
print(‘redis‘)
else:
print(‘密码存储类型输入错误‘)
return inner
return outter
@login_auth(‘file‘)
@index
def index():
time.sleep(1)
print(‘我是index函数‘)
res = index()
print(res)
请输入你的用户名>>>: syy
请输入你的用户密码>>>: 123
我是index函数
执行时间是: 1.0005395412445068
None
装饰器修复技术
#需求
1.用户查看被装饰函数的函数名的时候,查看到的就是被装饰函数本身
2.用户查看被装饰函数的注释的时候,查看到的就是被装饰函数的注释
#函数名问题
def outter(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
@outter
def index():
pass
print(id(index)) #2887421694024
print(index.__name__) #inner,查看函数名的字符串形式
#查看函数注释问题
def outter(func):
def inner(*args,**kwargs):
"""
我是装饰器内部的注释
:param args:
:param kwargs:
:return:
"""
print(‘哈哈‘)
res = func(*args,**kwargs)
return inner
@outter
def index():
"""
我是index内部的注释
:return:
"""
pass
print(help(index))
inner(*args, **kwargs)
我是装饰器内部的注释
:param args:
:param kwargs:
:return:
None
#装饰器修复技术,导入模块
#修复函数名问题
from functools import wraps
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
@outter
def index():
pass
print(id(index)) #1597239300168
print(index.__name__) #index
#修复注释问题
from functools import wraps
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
"""
我是装饰器内部的注释
:param args:
:param kwargs:
:return:
"""
print(‘哈哈‘)
res = func(*args,**kwargs)
return inner
@outter
def index():
"""
我是index内部的注释
:return:
"""
pass
print(help(index))
index()
我是index内部的注释
:return:
None
函数的递归
#递归
函数在调用阶段,直接或间接的又调用自己
#作用
递归的作用是为了解决使用循环的复杂程度
#格式
def func():
print(‘from func‘)
func()
func() #RecursionError:
def index():
print(‘from index‘)
login()
def login():
print(‘from login‘)
index()
login() #RecursionError:
#查看最大递归深度
import sys
print(sys.getrecursionlimit()) #1000,不是很精确
def func(n):
print(‘from func‘,n)
func(n+1)
func(1) #998
#修改最大递归深度
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(500)
def func(n):
print(‘from func‘,n)
func(n+1)
func(1) #498
#递归分为两个阶段
1.回溯,一次次重复的过程,这个重复的过程必须建立在上一次重复,问题的复杂度降低,直到有一个最终的结束条件
2.递推,一次次向回推导的过程,得到结果
#实例一
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
def age(n):
if n == 1:
return 18
return age(n-1) + 2
res = age(5)
print(res) #26
#实例二
#使用递归函数,不需要考虑循环的次数,只需要知道结束条件即可
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,]]]]]]]]]]
for i in l:
if type(i) == int:
print(i)
else:
for i in i:
if type(i) == int:
print(i)
else:
for i in i:
if type(i) == int:
print(i)
...
def get_num(L):
for i in L: #for循环取值,取完自动结束
if type(i) == int:
print(i)
else:
get_num(i) #使用递归,避免重复代码
get_num(l)
算法之二分法
#算法
解决问题的高效率的方法
#前提
二分法必须基于一个有序的容器类型
#实例
l = [1,3,5,12,57,99,101,150,177,199,345,...]
#代码1
num = 345
for i in l:
if num == i:
print(‘find it‘)
continue
#代码2
def get_num(L,target_num):
middle_index = len(L) // 2
print(L)
if target_num not in L:
print(‘该值不存在于列表中‘)
return
if target_num > L[middle_index]:
num_right = L[middle_index+1:]
get_num(num_right,target_num)
elif target_num < L[middle_index]:
num_left = L[0:middle_index]
get_num(num_left,target_num)
else:
print(‘找到了‘,target_num)
get_num(l,19)
三元表达式
#作用
使用if判断,从两个值中,取出一个
#三元表达式固定表达式
#条件成立,值1
#条件不成立,值2
值1 if 条件 else 值2
#应用场景
当结果只有两种可能性的情况下,可以使用三元表达式来简化代码
def my_max(x,y):
if x > y:
return x
return y
res = my_max(1,10)
print(res)
#实例1
#如果if后面的条件成立,返回if前面的值,否则返回else后面的值
x = 1
y = 19
res = x if x > y else y
print(res)
#实例2
is_free = input(‘请输入是否免费y/n>>>: ‘)
is_free = ‘免费‘ if is_free == ‘y‘ else ‘收费‘
print(is_free)
列表生成式
#作用
使用for循环,快速操作列表
#格式
[操作i for i in 容器]
[操作i for i in 容器 if 条件] #不能使用else
#一个列表中,在每一个元素的后面都添加一个后缀_dsb
l = [‘syy‘,‘sniko‘,‘shou‘,‘ji‘]
#代码1
ll = []
for i in l:
ll.append(‘%s_dsb‘%i)
print(ll)
#代码2
ll = []
for i in l:
ll.append(i + ‘_dsb‘) #python中,该方法连接字符串的效率很低
print(ll)
#代码3
L = [‘%s_dsb‘%i for i in l]
print(L)
#一个列表中,在以s开头的元素的后面都添加一个后缀_dsb
#for循环一次取出列表中的每一个元素
#然后交给if判断,条件成立的话,才会交给前面的if判断
#条件不成立,把该元素直接舍弃
l = [‘syy‘,‘sniko‘,‘shou‘,‘ji‘]
L = [‘%s_DSB‘%i for i in l if i.startswith(‘s‘)]
print(L)
字典生成式
#作用
使用for循环,快速生成一个字典
#格式
{i:j for i,j in 容器}
{i:j for i,j in 容器 if 条件}
#实例1
#l2中,元素只能比l1多(或者相等),不能比l1少
d = {}
l1 = [‘一‘,‘二‘,‘三‘]
l2 = [‘yi‘,‘er‘,‘san‘]
for i,j in enumerate(l1):
d[j] = l2[i]
print(d) #{‘一‘: ‘yi‘, ‘二‘: ‘er‘, ‘三‘: ‘san‘}
#实例2
l = [‘syy‘,123,‘pwd‘]
d = {i:j for i,j in enumerate(l)}
print(d) #{0: ‘syy‘, 1: 123, 2: ‘pwd‘}
l = [‘syy‘,123,‘pwd‘]
d = {i:j for i,j in enumerate(l) if j != ‘syy‘}
print(d) #{1: 123, 2: ‘pwd‘}
#enumerate()
函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
#格式
enumerate(容器, [start=0])
集合生成式
#作用
使用for循环,快速生成一个集合
#格式
{i for i in 列表 if 条件}
#实例
res = {i for i in range(10) if i !=5}
print(res) #{0, 1, 2, 3, 4, 6, 7, 8, 9}
生成器表达式
#作用
做成生成器,不浪费内存取值
#格式
(i for i in 列表 if 条件)
#实例
res = (i for i in range(10) if i !=5)
print(res) #<generator生成器 object <genexpr> at 0x0000028E1823A728>
for i in res:
print(i)
匿名函数
#定义
没有名字的函数
使用关键字lambda定义
#作用
临时创建,用完自动删除
#格式
#左边相当于函数的形参
#右边相当于函数的实参
#匿名函数通常不会单独使用,需要配合内置函数一起使用
(lambda 形参:操作)(实参)
#实例1
def my_sum(x,y):
return x+y
res = my_sum(1,2)
print(res)
res = (lambda x,y:x+y)(1,2)
print(res)
#匿名函数转换成函数
func = lambda x,y:x+y
print(func) #<function <lambda> at 0x00000116E8401EA0>,可以加括号执行
res = func(1,2)
print(res)
常用内置函数 max()
#原理
内部基于for循环,先将传入容器类型中的元素一个个取出
如果没有指定key(key对应的是一个函数)的时候,那么就直接比较取出的值(比较大小、ASCII码)
如果指定了key,那么max()函数会将这个元素交给这个函数,得到函数的返回值,再比较大小
#格式
max(l)
max(d,key=my_func)
#作用于列表,比较值的大小
l = [1,2,3]
print(max(l)) #内部使用的是for循环
l = [‘syy‘,‘zz‘]
print(max(l)) #zz
#作用于字典,使用ASCII码比较
#A-Z,65 90,a-z,95 122
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
print(max(d)) #syy
#max()函数的位置参数
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
def my_func(name):
return d[name]
print(max(d,key=my_func)) #egon
#内置函数max()与lambda表达式连用
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
print(max(d,key=lambda name:d[name])) #egon
min()
#格式
max(l)
max(d,key=my_func)
#作用于列表,比较值的大小
l = [1,2,3]
print( min(l)) #内部使用的是for循环
l = [‘syy‘,‘zz‘]
print(min(l)) #syy
#作用于字典,使用ASCII码比较
#A-Z,65 90,a-z,95 122
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
print(min(d)) #egon
#min()函数的位置参数
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
def my_func(name):
return d[name]
print( min(d,key=my_func)) #js
#内置函数min()与lambda表达式连用
d = {‘syy‘:666,‘egon‘:888888,‘js‘:233}
print(min(d,key=lambda name:d[name])) #js
map()
#map()函数
映射,把列表、元组、集合的所有元素,同等操作
#格式
map(lambda 形参:操作:作用对象)
#实例1
l = [1,2,3,4,5]
print(map(lambda x:x+1,l)) #<map object at 0x000001F55A38F860>,生成器
res = map(lambda x:x+1,l)
for i in res: #使用for循环,取出生成器中的值
print(i) #2,3,4,5,6
print(list(res)) #使用list(本质还是for循环)
#实例二
l = {‘1‘,‘2‘,‘3‘,‘4‘,‘5‘}
res = map(lambda x:x+‘_dsb‘,l)
print(set(res)) #{‘4_dsb‘, ‘5_dsb‘, ‘2_dsb‘, ‘3_dsb‘, ‘1_dsb‘}
zip()
#zip()函数
拉链,把两个容器中对应的一对儿元素绑定到一起组成元组
#格式
zip(l1,l2,...)
#实例
#元素多了无效
l1 = [11,22,33]
l2 = [‘js‘,‘syy‘,‘egon‘]
print(zip(l1,l2)) #<zip object at 0x0000027A904D9888>,生成器
res = zip(l1,l2)
print(type(res)) #<class ‘zip‘>,zip数据类型
print(list(res)) #[(11, ‘js‘), (22, ‘syy‘), (33, ‘egon‘)],数据类型转换
l3 = [‘a‘,‘b‘,‘c‘]
print(list(zip(l1,l2,l3))) #[(11, ‘js‘, ‘a‘), (22, ‘syy‘, ‘b‘), (33, ‘egon‘, ‘c‘)]
filter()
#filter()
过滤
#格式
filter(lambda 形参:操作,作用对象)
#实例1
l = [1,2,3,4,5]
res = filter(lambda x:x !=3,l)
print(res) #<filter object at 0x000001E546EEF860>,生成器
print(list(filter(lambda x:x !=3,l))) #[1, 2, 4, 5]
sorted()
# sorted()
排序,默认正序
可以排列数字,也可以排列字符串
#格式
sorted(l,reverse=False)
#实例
l = [‘syy‘,‘nb‘,‘haha‘]
print(sorted(l)) #[‘haha‘, ‘nb‘, ‘syy‘],正序
l = [‘syy‘,‘nb‘,‘haha‘] #[‘syy‘, ‘nb‘, ‘haha‘],反序
print(sorted(l,reverse=True))
reduce()
# reduce()
取值,再操作
#格式
reduce(lambda 形参:操作,作用对象,N)
#实例1
#如果N指定了,那么N为初始值,如果N不指定,按照以下规律
#第一次先获取两个元素,相加
#之后每次获取一个,与上一次的结果,再相加
from functools import reduce
l = [1,2,3,4,5,6]
res = reduce(lambda x,y:x+y,l)
print(res) #21
迭代器
#什么是迭代器
迭代:更新换代(重复)的过程,每次迭代都必须基于上一次的结果
迭代器:迭代取值的工具
#为什么要用迭代器
迭代器提供了一种不依赖于索引取值的一种方式
#可以迭代取值的数据类型
字符串、列表、元组、字典、集合
#怎么用迭代器
#对有序的数据类型(字符串、列表、元组),实现迭代 --- while循环
l = [1,2,3,4,5]
n = 0
while n < len(l):
print(l[n])
n+=1
#对无序的数据类型(字典、集合),实现迭代 --- 使用迭代器
可迭代对象
#只要内置有__iter__方法的,都叫做可迭代对象
#双下划线开头、结尾的方法,可以读‘双下+方法‘
#可迭代对象有,字符串、列表、元组、字典、集合、文件
#不可迭代对象有,整型、浮点型、布尔值
#迭代器对象是可迭代对象使用__iter__方法的返回值
a = 1
b = 1.1
c = ‘哈哈‘
d = [1,2,3]
e = {‘name‘:‘syy‘}
f = {1,2,3}
g = (1,2,3)
h = True
i = open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘)
j = len(‘哈哈‘)
a.__i
b.__i
c.__iter__()
d.__iter__()
e.__iter__()
f.__iter__()
g.__iter__()
h.__i
i.__iter__()
j.__i
#可迭代对象执行__iter__,得到的就是迭代器对象
res = c.__iter__()
print(res) #<str_iterator object at 0x000001A54DC24780>
res = d.__iter__()
print(res) #<list_iterator object at 0x000001A54DC24978>
res = e.__iter__()
print(res) #<dict_keyiterator object at 0x000001A54D928598>
res = f.__iter__()
print(res) #<set_iterator object at 0x000001A54DC3A360>
res = g.__iter__()
print(res) #<tuple_iterator object at 0x000001A54DC24978>
res = i.__iter__()
print(res) #<_io.TextIOWrapper name=‘E:\python_test\xxxx.txt‘ mode=‘rt‘ encoding=‘utf-8‘>
#迭代器的使用
print(len(c))
print(c.__len__())
res = map(lambda x:x+1,l)
print(res) #<map object at 0x000001AF716CF860>
l1 = [1,2,3]
l2 = [‘yi‘,‘er‘,‘san‘]
print(zip(l1,l2)) #<zip object at 0x000002D38D179888>
迭代器对象
#迭代器对象(就是迭代器)
1.内置有__iter__方法
2.内置有__next__方法
#迭代器对象一定是可迭代对象,但是可迭代对象不一定是迭代器对象
#迭代器对象的验证
c = ‘哈哈‘
d = [1,2,3]
e = {‘name‘:‘syy‘}
f = {1,2,3}
g = (1,2,3)
i = open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘)
res = c.__iter__()
print(res) #<str_iterator object at 0x000001A54DC24780>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
res = d.__iter__()
print(res) #<list_iterator object at 0x000001A54DC24978>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
res = e.__iter__()
print(res) #<dict_keyiterator object at 0x000001A54D928598>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
res = f.__iter__()
print(res) #<set_iterator object at 0x000001A54DC3A360>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
res = g.__iter__()
print(res) #<tuple_iterator object at 0x000001A54DC24978>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
res = i.__iter__()
print(res) #<_io.TextIOWrapper name=‘E:\python_test\xxxx.txt‘ mode=‘rt‘ encoding=‘utf-8‘>
iter_1 = res
iter_1.__iter__()
iter_1.__next__()
#迭代器对象的取值
l = [1,2,3,4]
iter_1 = l.__iter__()
res = iter_1.__iter__()
print(res) #<list_iterator object,本身
print(iter_1.__next__()) #1
print(iter_1.__next__()) #2
print(iter_1.__next__()) #3
print(iter_1.__next__()) #4
print(iter_1.__next__()) #StopIteration
#文件对象本身就是一个可迭代对象、迭代器对象
i = open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘)
res = i.__iter__()
res = i.__next__()
print(res) #<_io.TextIOWrapper name=‘E:\python_test\xxxx.txt‘ mode=‘rt‘ encoding=‘utf-8‘>
#迭代器对象执行__iter__,得到的还是迭代器对象本身
i = open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘)
res = i.__iter__()
print(res is i) #True
print(i is i.__iter__().__iter__().__iter__()) #True
#问题
__iter__就是生产迭代器对象的方法
文件对象本身就是迭代器对象,为什么还内置__iter__方法呢?
答:为了文件对象可以和别的接迭代对象,可以一起使用for循环,如果迭代器对象没有__iter__,那么文件对象调用__iter__的时候就会报错
#异常有两大类
1.语法结构错误,需要当成修改,否则无法捕获
2.逻辑错误,异常捕获可以处理
#异常捕获
d = [1,2,3]
iter_1 = d.__iter__()
while True:
try:
print(iter_1.__next__())
except StopIteration:
print(‘母鸡下蛋完成‘)
break
#万能异常捕获(前提是逻辑错误)
while True:
try:
fve
except Exception:
break
#迭代器取值的优点
1.不依赖于索引取值
2.内存中永远只占用一份空间,不会导致内存溢出
#迭代器取值的缺点
1.只能依次取值,不能后退
2.取完值之后报错StopIteration(异常捕获)
#ps:
__iter__() 等价于 iter()
__next__() 等价于 next()
__len__() 等价于 len()
for循环内部原理
#for循环简单格式
#for循环后面的关键字in,后面跟的是一个可迭代对象
l = [1,2,3]
for i in l:
print(i)
#for循环内部本质
1.将in后面的对象调用__iter__方法,转换成迭代器对象
2.调用__next__,迭代取值
3.内部有异常捕获,当__next__报这个错StopIteration,自动结束循环
#for循环完整格式
for i in 可迭代对象:
try:
循环体代码
except StopIteration:
break
生成器(自定义迭代器)
#生成器
生成器本质上就是迭代器,只不过是用户自定义的迭代器
使用关键字yield,自定义迭代器
#当函数内有yield关键字的时候
调用函数之前,该函数与普通函数一样
当‘调用函数的时候‘,不会执行函数体代码,而是将函数初始化,变成生成器
#yield,如果函数体代码中有yield关键字,那么函数加括号执行的时候,不会触发函数体代码的运行
def func():
print(‘first‘)
yield
print(‘second‘)
func() #变成生成器
res = func()
print(res)
print(res.__next__())
<generator object func at 0x0000016BC5C4A728>
first
None
#yield后面跟的值,就是调用迭代器__next__,能得到的值
def func():
print(‘first‘)
yield 233
print(‘second‘)
res = func()
print(res)
print(res.__next__())
print(res.__next__()) #StopIteration
<generator生成器 object func at 0x000001298930A728>
first
233
second
#yield,既可以返回一个值,又可以返回多个值(元组)
def func():
print(‘first‘)
yield 233,4,5
print(‘second‘)
res = func()
print(res)
print(res.__next__())
print(res.__next__())
print(res.__next__()) #StopIteration
<generator object func at 0x0000014569B9A728>
first
(233, 4, 5)
second
#函数体代码中有多个yield
def func():
print(‘first‘)
yield 1
print(‘second‘)
yield 2
print(‘third‘)
yield 3
print(‘fourth‘)
res = func()
print(res)
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__()) #StopIteration
<generator object func at 0x0000021A5A67A728>
first
1
second
2
third
3
fourth
#自定义迭代器(生成器)
for i in range(1,10,2): #内置函数
print(i)
def my_range(start=0,end,step=1): #自定义迭代器(生成器)
while start < end:
print(start)
yield start
start+=step
res = range(1,10,1)
print(res.__n) #内置range不是迭代器对象
res = my_range(1,10,1) #先运行,再调用
print(res.__next__())
#函数体外部向函数体内部传参的方式
1.位置参数
2.闭包函数
#函数体内部向函数体外部传参的方式
1.关键字global
2.函数return
3.yield
#yield支持外界为其传参
#必须先将代码运行到yield,才能为其传值
def dog(name):
print(‘%s 准备开吃‘%name)
while True:
food = yield
print(‘%s 吃了 %s‘%(name,food))
func = dog(‘js‘)
func.__next__() #返回空值,不能省略,含有yield的函数,调用__next__才会执行
func.send(‘糖果‘) #send(),给yield传参,调用__next__
func.send(‘包子‘)
js准备开吃
js吃了"糖果"
#yield
1.yield提供的是一种自定义生成器的方式
2.yield可以将函数的运行状态停止
3.yield可以返回值
#yield与return之间的相同点
1.都可以返回值,并且都可以返回多个值
#yield与return之间的不同点
1.yield可以返回多次值,return只能把所有的值一次返回,然后立即结束
2.yield可以接收外部传入的值
生成器表达式
#作用
做成生成器,不浪费内存取值
生成器不会主动执行任何一行代码,必须使用__next__方法,才会触发代码运行
#格式
(i for i in 可迭代对象 if 条件)
#实例
res = (i for i in range(10) if i !=5)
print(res) #<generator生成器 object <genexpr> at 0x0000028E1823A728>
#生成器取值1
for i in res:
print(i)
#生成器取值2
res = (i for i in range(5) if i !=3)
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
#应用场景1 -- 容器内的元素很多
res = (i for i in range(100000000) if i !=5)
#应用场景2 -- 统计文件中的字符个数
f = open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘)
data = f.read() #占用内存较多
print(len(data))
f.close()
with open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘) as f:
n = 0
for line in f: #生成器的本质方法
n+=len(line)
print(n)
with open(r‘E:python_testxxxx.txt‘,mode=‘rt‘,encoding=‘utf-8‘) as f:
g = (len(line) for line in f)
print(sum(g))
#sum()函数的本质
l = [1,2]
res = sum(l)
print(res) #3
l = [1,2]
n = 0
for i in l:
n+=i
print(n)
l = [1,2]
res1 = l.__iter__().__next__()
res2 = l.__iter__().__next__()
print(res1+res2)
l = [1,2]
res = (i for i in l)
for i in res:
print(i)
生成器面试题
def add(n,i):
return n+i
def test():
for i in range(4):
yield i
g = test() #0,1,2,3
for n in [1,10]:
g = (add(n,i) for i in g)
"""
第一次循环:g = (add(1,i) for i in test())
第二次循环:g = (add(10,i) for i in g)
"""
res = list(g)
"""
for i in (add(10,i) for i in test()): #上述循环的2层生成器拆分开,n=10
add(10,i)
"""
print(res) #[20, 21, 22, 23]
常用的内置函数
#abs(),取绝对值
res = abs(-1)
print(res) #1
#all(),全部为True为True
l = [0,1,2,3]
print(all(l)) #False
#any(),有一个为True为True
print(any(l)) #True
#十进制转其他进制,bin()、oct()、hex()
print(bin(10))
print(oct(10))
print(hex(10))
0b1010 #二进制
0o12 #八进制
0xa #十六进制
#其他进制转十进制,使用int()
print(int(‘1010‘,2))
print(int(‘12‘,8))
print(int(‘a‘,16))
#转换为布尔值,bool()
print(bool(1)) #True,非零数都为True
print(bool(0)) #False
#字符串转二进制数,encode()、bytes()
s = ‘哈哈‘
print(s.encode(‘utf-8‘))
print(bytes(s,encoding=‘utf-8‘))
#二进制数转字符串,decode()函数
s = ‘哈哈‘
res1 = s.encode(‘utf-8‘)
res2 = res1.decode(‘utf-8‘)
print(res2)
#可调用的,就是可以加括号执行相应功能的,callable()
l = [1,2,3]
print(callable(l)) #False
#将数字转换成字母,使用chr()函数,可用于验证码
print(chr(97)) #a
print(chr(122)) #z
#将字母转换成数字,使用ord()函数
print(ord(‘a‘)) #97
print(ord(‘z‘)) #122
print(ord(‘A‘)) #65
print(ord(‘Z‘)) #90
#函数dir(),返回对象在名称空间中的所有有关的名字
l = [1,2,3]
print(dir(l)) #[‘__add__‘, ‘__class__‘, ‘__contains__‘, ‘__delattr__‘, ‘__delitem__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__getitem__‘, ‘__gt__‘, ‘__hash__‘, ‘__iadd__‘, ‘__imul__‘, ‘__init__‘, ‘__init_subclass__‘, ‘__iter__‘, ‘__le__‘, ‘__len__‘, ‘__lt__‘, ‘__mul__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__reversed__‘, ‘__rmul__‘, ‘__setattr__‘, ‘__setitem__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘append‘, ‘clear‘, ‘copy‘, ‘count‘, ‘extend‘, ‘index‘, ‘insert‘, ‘pop‘, ‘remove‘, ‘reverse‘, ‘sort‘]
import b #导入b.py文件
print(dir(b))
#divmod()函数,得到商和余数,可用于分页器
print(divmod(100,10))
print(divmod(100,9))
(10, 0)
(11, 1)
total_num,more = divmod(100,9) #总数据量,每页的数据量
if more:
total_num+=1
print(‘总页数是: ‘,total_num)
#enumerate()函数,枚举(一个个列出来),可用来打印msg
l = [‘a‘,‘b‘]
for i,j in enumerate(l,1):
print(i,j)
1 a
2 b
#evel()函数,可用来识别字符串中的简单代码(去掉引号),不能识别字符串中的逻辑代码
s = ‘print("hello world")‘
print(eval(s))
hello world
None
s = """
x = 1
y = 2
print(x+y)
"""
print(eval(s)) #SyntaxError
#exec()函数,即可以用来识别字符串中的简单代码,又可以识别字符串中的逻辑代码
s = ‘print("hello world")‘
print(exec(s))
s = """
x = 1
y = 2
print(x+y)
"""
print(exec(s))
hello world
None
3
None
#format()函数,三种玩法
{}占位
{index}索引占位
{name}指名道姓的占位
#globals()函数,打印全局名称空间中的变量,无论在哪
print(globals()) #{‘__name__‘: ‘__main__‘, ‘__doc__‘: None, ‘__package__‘: None, ‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x000001CE953EC2B0>, ‘__spec__‘: None, ‘__annotations__‘: {}, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__file__‘: ‘E:/python_test/a.py‘, ‘__cached__‘: None}
#locals()函数,打印局部名称空间中的变量(在哪打印哪的)
def test():
x =111
print(locals())
test() #{‘x‘: 111}
#help()函数,查看函数内的帮助
def test():
"""
:return: 没有
"""
x =111
print(help(test))
test()
:return: 没有
#isinstance()函数,验证数据类型
x = 1
print(type(x)) #<class ‘int‘>
print(type(x) is int) #True
print(isinstance(x,int)) #True
#pow()函数,次方
print(pow(2,3)) #8
#round()函数,四舍五入
print(round(1.49)) #1
print(round(1.59)) #2
#isalpha()函数,判断字符串中有没有数字
s = ‘syy‘
print(s.isalpha()) #True
s = ‘syy123‘
print(s.isalpha()) #False
#数据类型的转换
str()
int()
float()
set()
list()
dict()
tuple()
bool()
get()
open()
bytes()
面向过程编程
# 面向过程编程
就类似于设计一条流水线
#好处
将复杂的问题流程化、简单化
#坏处
可扩展性差,一旦修改,整体都会搜到影响
#注册功能
1.获取用户输入(前端)
2.处理用户信息(后端)
3.存储到文件(数据库)
def get_info():
while True:
username = input(‘请输入你的用户名>>>: ‘).strip()
if not username.isalpha():
print(‘用户名不能包含数字‘)
continue
password = int(input(‘请输入你的密码>>>: ‘).strip())
confirm_password = int(input(‘请再次确认你的密码>>>: ‘).strip())
if password == confirm_password:
operate_data(username,password)
print(‘注册成功‘)
break
else:
print(‘2次输入密码不一致‘)
continue
def operate_data(username,password):
res = ‘%s|%s
‘%(username,password)
save_data(res,‘filename‘)
def save_data(res,filename):
with open(r‘filename‘,‘a‘,encoding=‘utf-8‘) as f:
f.write(res)
get_info()
以上是关于装饰器生成式迭代器的主要内容,如果未能解决你的问题,请参考以下文章
day5--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数
python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化