装饰器生成式迭代器

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--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数

py8 列表生成式 装饰器 迭代器 生成器

Python的生成器 迭代器 装饰器

python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化