• 装饰器、生成式、迭代器


    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()
    
  • 相关阅读:
    关于跨域策略文件crossdomain.xml文件
    fl.motion SDK包下载,可用来设置显示对象的连读、饱和度、色调、对比度
    ActionScript工程如何使用Flash CS的fl包中的UI组件(转)
    无法将 flash.display::BitmapData 转换为 flash.display.Bitmap
    服务器托管
    男人会为女人改变多少
    AS3组件之Slider滑块拖动条
    jQuery验证使用
    十进制、十六进制、二进制习题
    jQuery层次选择器
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/14059480.html
Copyright © 2020-2023  润新知