您的位置:新葡亰496net > 奥门新萄京娱乐场 > 函数进级,Python底蕴之函数

函数进级,Python底蕴之函数

发布时间:2019-11-15 12:45编辑:奥门新萄京娱乐场浏览(91)

    一、函数

      我们能够用生龙活虎段代码来完结大家要求的功用,不过当大家必要重复使用这段代码时,复制粘贴而不是三个酷的格局,大家得以用到函数来落到实处那风流倜傥必要

    一、函数

      1、什么是函数:函数正是统筹某后生可畏功力的工具

        函数的运用必需比照先定义、后调用的基准

          事先计划工具的进度即函数的概念

          拿来就用即为函数的调用

        函数分为两大类:1、内置的函数   2、自定义的函数

    生机勃勃、函数定义

    1、为啥要用函数

      2、为何要用函数:

          2.1 程序的集体结构不明晰、可读性差

          2.2 万众一心冗余代码过多

          2.3 程序的可增添性极差

    函数是逻辑结构化和进度化的生机勃勃种编程方法,通过叁个函数名封装好生龙活虎串用来成功某风流浪漫一定成效的代码

        a、制止代码重用

      3、怎么用函数

    函数的定义:

        b、进步代码的可读性

      3.1概念函数  

      3.1.1 语法 

    # def 函数名(参数1,参数2,参数3,...):
    #     """
    #     文档注释
    #     """
    #     code1
    #     code2
    #     code3
    #     ...
    #     return 返回值
    

      3.1.2 定义函数阶段发生怎么样事:只检查实验语法,不施行代码

    def foo(): # foo=函数的内存地址
        print('first')
        print('sencod')
        print('asdfsadfasdfas')
        print('third')
    foo()
    
    # # 定义阶段
    def foo():
        print('from foo')
        bar()
    
    def bar():
        print('from bar')
    
    #调用阶段
    foo()
    

     3.1.3 定义函数的三种样式

            1.无参函数

    def bar():
        print('from bar')
    bar()
    

            2.有参函数

    def func2(x,y):
        # x=1
        # y=3
        if x > y:
            print(x)
        else:
            print(y)
    
    func2(1,3)
    

            3.空函数(做占位使用卡塔尔

    def foo():
        pass
    

    def 函数名(参数1,参数2....):

    2、函数的调用

     3.2调用函数

        语法:函数名()   

        调用函数发生了:1、根据函数名找到函数的内部存款和储蓄器地址  2、函数的内部存款和储蓄器地址加括号能够触发函数体代码的实施

        调用函数的二种办法:

          3.2.1 语句

    def f1():
        print('from 1')
    f1()
    

          3.2.2表达式

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    res=max(1,2)*10
    print(res)
    

          3.2.3用作参数传给别的函数

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    res=max2(max2(1,2),3)
    print(res)
    

     

      ''注释''

       返回值=函数名(参数1,参数2)

     4、函数的重返值

      1、什么是函数的再次回到值:函数体代码运维的叁个成果

      return 值:

        重返值未有项目节制、再次回到值未有个数约束

          逗号分割三个值:重回贰个元组

          二个值:重回二个值

          未有return:暗中认可重临None

    图片 1图片 2

    def login():
        while True:
            username=input('name>>: ').strip()
            pwd=input('password>>:').strip()
            if username not in user_dic:
                print('not found')
                continue
            if pwd != user_dic[username]:
                print('pwd error')
                continue
            print('login successful')
            return username
    print(login())
    

    return 登录名

    # return是函数结束的标志:
    # 函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的值当作本次调用的结果返回
    

      函数体 

       函数定义---再次来到值

    二、函数的参数

    def func1():  #定义函数
        print('this is a function')  #函数体
    func1()  #调用函数
    
    #通常无参函数不需要返回值,有参函数需要有返回值
    def func1(name):  #带参数的形式
        print('%s is a good man'%name)
    func1('egon')
    
    #关于函数的返回值,如果没有指定,默认是None
    #函数与过程的定义就是过程没有返回值,用完之后就没有了,而函数有返回值
    def func1(name):
        print('%s is a good man'%name)
    print(func1('egon')) 
    

       关键字:return

      1、函数的参数分为两大类:形参、实参

        形参:指的是在概念函数时,括号指定的参数,本质就是变量名

        实参:指的是在调用函数时,括号内流传的值,本质正是值

      独有在调用函数时才会在函数体内发生实参(值)与形参(变量名)的绑定关系

      该绑定关系只在调用函数时权且生效,在调用函数甘休后就灭亡绑定

        def foo(x,y): #x=1,y=2
            print(x)
            print(y)
        # a=1
        # b=2
        # foo(a,b)
        foo(1,2)
    

    -->  egon is a good man

    3、return的作用:

      2、地方参数

        地点形参:在概念函数时,根据从左到右的逐一依次定义的形参称之为地方形参

           ps:但凡是遵照岗位定义的形参,在调用函数时必需为其传值,多二个不行少二个也丰硕

        地方实参:在调用函数时,遵照从左到右的依次依次传入的值

           ps:传值是按部就班顺序与形参风流洒脱 一相应

    def foo(x,y,z):
        print(x,y,z)
    # foo(1,2)
    foo(1,2,3,4)#多传一个值  报错
    # foo(1,2,3)
    foo(3,2,1)
    

        None

        a、甘休函数的进行

       3、关键字实参:

             在调用函数时,根据key=value的样式定义的实参,称之为关键字实参
          注意:
          1、在传值时方可完全打乱顺序,但依旧能钦赐道姓地为钦赐的参数字传送值
          2、能够在调用函数时,混合使用地点实加入重要字实参
          不过地点实参必需跟在首要字实参侧面
          并且不能够为叁个形参重复传值

    def register(name,sex,age):
        print(name)
        print(sex)
        print(age)
    register(sex='male',name='mogu',age=18)
    register('mogu',age=18,sex='male')#混合使用
    

    函数的亮点:1.代码引用

        b、再次回到要重返的值

      4、默认参数

        在概念函数时,就早就为一些参数绑定值,称为暗中同意参数

          ps:1、在概念阶段就已经有值,意味在调用阶段能够不用传值

            2、暗许形参必需放在地点形参的末端

            3、暗许形参的值只在概念阶段生效二次,在函数定义之后爆发的改动无效

            4、默许形参的值日常应该是不行变类型

      暗许形参:大好多情形下值都相似

      地点形参:大多数状态值都分歧

    def foo(x,y,z=3):
        print(x)
        print(y)
        print(z)
    foo(1,2)
    foo(1,2,4) #传值后改变了默认值
    

    图片 3图片 4

    def register(name,age,sex='female'):
        print(name)
        print(sex)
        print(age)
    register('mogu',18)
    register('xiaohuochai',28)
    register('momo',19)
    register('张三',33,'male')
    

    暗许与任务示例

    m=10
    def foo(x,y,z=m):
        print('x:%s' %x)
        print('y:%s' %y)
        print('z:%s' %z)
    m=111111111    #定义阶段就是10   此更改无效
    foo(1,2)
    

    图片 5图片 6

    def foo(name,hobby,l=None):
        if l is None:
            l=[]
        l.append(hobby)
        print('%s 的爱好是 %s' %(name,l))
    l1=[]
    foo('mogu','read',l1) #l1=['read']
    foo('xiaomogu','movie')  #l1=['read','music']
    foo('nvhai',' 卖火柴')
    foo('张三','吹牛')
    foo('关二爷','耍大刀')
    

    暗中认可形参示例2

          2.保持生龙活虎致性,易于维护

    4、再次回到值的三种意况

      5、可变长度的参数

        可变长度指的是在调用函数时,函数参数的个数能够不定点

    而是实参终归是要为形参传值的,针对二种样式实参个数不稳固,对应着形参也必须有二种减轻方案

    那就是 * 和 ** 来分别管理溢出位置实参加溢出关键字实参

          3.可扩大性好

        a、重返值为None

      5.1 * 会将溢出的职位实参存成元组,然后赋值给紧跟其后的变量名

    5.1.1 形参中带 *

    def foo(x,y,*z): #z=(3,4,5,6,7,8)
        print(x)
        print(y)
        print(z)
    foo(1,2,3,4,5,6,7,8)
    

    5.1.2  形参中带*   实参中带 * ,诀窍:但凡遇到实参中带*  都先将其打垮成任务实参,然后寻思传值

    def foo(x,y,*z): #z=(3,4,5,6,7,8)
        print(x)
        print(y)
        print(z)
    foo(1,2,[3,4,5,6,7,8]) #z=([3,4,5,6,7,8],)
    foo(1,2,*[3,4,5,6,7,8]) #foo(1,2,3,4,5,6,7,8)====>z=(3,4,5,6,7,8)
    foo(1,2,*'hello') #foo(1,2,'h','e','l','l','o')
    foo(1,*[2,3,4,5,6])  #foo(1,2,3,4,5,6)
    

    5.1.3 实参中带 *  秘籍同上

    def foo(x,y,z):
        print(x,y,z)
    l = ['mogu', 'huochai', 'nvhai']
    foo(*l) # foo('mogu', 'huochai', 'nvhai')
    

    在乎:1.函数必需先定义,在选择,和变量相同,在概念前使用会报错

    图片 7图片 8

    5.2  ** 会将溢出的基本点字实参存成字典,然后赋值给紧跟其后的变量名

    5.2.1 形参中带 **

    图片 9图片 10

    def foo(x,y,m,n,**z): #
        print(x)
        print(y)
        print(m)
        print(n)
        print(z)
    foo(1,2,n=10,m=20,a=1,b=2,c=3)
    

    View Code

    5.2.2 形参中带 **  实参中带 **  秘诀:但凡遭逢实参中带**  都先将其击败成职分实参,然后思量传值

    def foo(x,y,**z): #
        print(x,y,z)
    foo(1,2,**{'a':1,'b':2,'c':2}) #foo(1,2,c=2,a=1,b=2)
    foo(1,**{'a':1,'b':2,'c':2,'y':111}) #foo(1,c=2,a=1,b=2,y=111)
    

    5.2.3 实参中带**

    def foo(x,y,z):
        print(x,y,z)
    foo(1,**{'y':111,'z':222}) #foo(1,y=111,z=222)
    foo(**{'z':1,'y':2,'x':3}) #foo(y=2,z=1,x=3)
    

       2.函数在概念阶段只检查测试语法错误,不会进行代码,所以固然在函数体内有未定义的变量名,在函数未调用前也不会报错

    def mylen():
        """计算s1的长度"""
        s1 = "hello world"
        length = 0
        for i in s1:
            length = length 1
        print(length)
    
    
    str_len = mylen()
    print(str_len)
    

       6、 *args   和  **kwargs

    可选用任性长度,大肆格式的参数(ps:实参中:地点实参必需在首要字实参的左边卡塔尔

    def foo(*args,**kwargs):
        print(args,kwargs)#可完美转嫁
    
    foo(任意长度,格式的实参)
    

    图片 11图片 12

    #需要将外层函数的参数格式原封不动的转嫁给其内部调用的函数,就需要以下
    def index(name,age,sex):
        print('name:%s age:%s sex:%s' %(name,age,sex))
    def foo(*args,**kwargs):
        index(*args,**kwargs)#可完美转嫁
    
    foo('mogu',sex='male',age=18)#虽然调用的是foo函数,但是需要遵循        
                                                       index函数的参数规则
    

    示例

     

       3.函数的重返值能够是自由档期的顺序,若是是回到三个值,一定是元组情势

    不写return

    三、函数对象

      函数是第生龙活虎类对象,意味着函数能够当作数据去行使

    def foo():
        print('from foo')
    

    1、能够被引述

    print(foo)
    func=foo
    print(func)
    func()
    

    2、能够看做参数传给其它贰个函数

    def bar(x): #x=foo的内存地址
        print(x)
        x()
    bar(foo)
    

    3、能够当作函数的重回值

    def bar():
        return foo
    f=bar()
    # print(f is foo)
    f()
    

    4、能够作为容器类型的要素

    def f1():
        print('from f1')
    def f2():
        print('from f2')
    l=[f1,f2]   #列表内全为函数体
    print(l)
    l[1]()
    l[0]()
    

     

       4.return 的效率是终止函数的实践,return只进行二次,前边的开始和结果不推行

    图片 13图片 14

    四、函数的嵌套调用

      1、嵌套调用

      在调用一个函数时,在那之中间的代码又调用其余的函数

    def bar():
        print('from bar')
    
    def foo():
        print('from foo')
        bar()
    foo()
    

    图片 15图片 16

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    #
    def max4(a,b,c,d):
        res1=max2(a,b)
        res2=max2(res1,c)
        res3=max2(res2,d)
        return res3
    
    print(max4(1,2,3,4))
    

    数值大小相比较

     

      2、嵌套定义:在三个函数的在这之中又定义了其它三个函数

    def f1():
        x=1
        def f2():
            print('from f2')
        print(x)
        print(f2)
        f2()
    f1()
    

     

    二、函数参数

    def ret():
        print(111)
        return
        print(222)
    
    re = ret()
    print(re)
    

    五、名称空间和成效域

    1、什么是称呼空间:名称空间是寄存名字与值绑定关系的地点

      要取到值必需通过名字能力找,而名字又在称呼空间中存放着,所以取值时首先去名称空间中找名字

        找到了名字自然拿到值的内部存款和储蓄器地址。

    函数的参数分为情势参数和骨子里参数,在函数定义的时候,函数名后边括号里的就是花样参数,在函数调用的时候,传递的参数是实在参数。格局参数只在函数内部有效,外界不能援用。

    只写return

    2、名称空间分为三种:

      2.1 放置名称空间:贮存的python解释器自带的名字

          生命周期:在解释器运行时发生,在解释器关闭时回笼

      2.2 全局名称空间:除了内置的与一些的之外名字都归属全局名称空间

          生命周期:在程序文件进行时就立时发出,在程序实践实现后就回笼

    x=1
    y=2
    def foo():
        x=1
        y=2
    foo()
    if y > x:
        print(x)
    z=3
    # 其中:x,y,foo,z都是全局名称空间中的名字
    

      2.3 黄金时代部分名称空间:贮存的是函数内部定义的名字

          生命周期:在调用时权且生效,在函数截至后当即回笼

    len=100
    # print(len) # 站在全局查找
    
    def foo():
        len=2222
        print(len)  #先在局部查找
    foo()
    

    1.形参

    图片 17图片 18

    加载顺序

      内置名称空间--->全局名称空间--->局地名称空间

      加载名称空间的目标是为着将名字与值的绑定关系寄放起来

      而存的指标是为着取,也正是当大家搜求名字时,必然是在三者之一中找到

    1卡塔 尔(阿拉伯语:قطر‎地点参数:依据从左到右的相继依次定义的参数 def foo(x,y,z)

    def ret():
        print(111)
        return None
        print(222)
    
    re = ret()
    print(re)
    

    找出顺序

      局地名称空间--->全局名称空间--->内置名称空间

      基于当前所在地点以后寻觅

    x=100
    y=200
    
    # 强调:函数的形参名属于局部名称空间
    def foo(x,y):
        print(x,y)
    
    foo(1,2)    #print结果为1,2
    

    图片 19图片 20

    x=2222
    def f1():
        # x=1
        def f2():
            # x=2
            print('from f2',x)
        f2()
    
    x=111
    f1()   #print结果为   from f2  111
    

    ps:全局查找

    图片 21图片 22

    x=2222
    def f1():
        # x=1
        def f2():
            x=2           #先在局部查找
            print('from f2',x)
        f2()
    
    x=111
    f1()          #结果为  from f2   2
    

    ps:局地查找

     

      地点形参必得被传值,且多叁个少三个都极其

    return None

    3、作用域

      域指的是限量,成效域指的是法力范围

        3.1.全局意义范围:包括内置名称空间与大局名称空间中的名字

            特点:全局有效,全局存活

        3.2.局地功能范围:包蕴部分名称空间中的名字

            特点:局地有效,一时存活

    图片 23图片 24

    x=1
    
    def f1():
        def f2():
            def f3():
                x=3   #函数此处有值  所有全局的x=1 并不会取
                print(x)
            f3()
        f2()
    
    f1()   #函数调用会先在函数内部寻找,所有结果为 3
    #
    def foo():
        print(x)
    
    foo()  #而此处函数内部未定义x  所以会找全局   1
    

    功能范围

    #如何打破函数层级带来的访问限制,让我能够在任意位置都可以访问到一个内部函数
    # 基于函数对象的概念将一个内部函数返回(return)到全局使用,从而打破了函数的层级限制
    

    2卡塔尔默许参数:在函数定义阶段就已经为形参赋值,调用阶段不赋值也可能有默许值 def foo(x,y=10)

        b、再次来到值不为None

    3.3.函数的功用域关系是在函数定义阶段就曾经定位死的,与函数的调用地点非亲非故

      即在调用函数时料定要跑到定义函数的职分寻找功效域关系

    图片 25图片 26

    x=111
    def outter():
        x=33333
        def inner():
            print('from inner',x)
            # x=4444   #此处再定义会报错
        return inner
    x=222
    f=outter() #f=指向outter.locals.inner
    f()     #结果为from inner  33333
    

    功用域关系

     

      值常常变化的动静,平常定义成职责参数,可是值在大相当多意况下不改变的景观下,能够定义成私下认可参数

             1、再次来到多少个值

    3.4.  global 和  nonlocal

    global :在部分评释名字是缘于全局的

    x=1
    def func():
        global x   #声明x为全局
        x=2          #所以此处即修改了全局的x
    func()
    
    print(x)  #结果为 2
    

    nonlocal :注脚变量来自当前层外层(必须在函数内卡塔尔

    图片 27图片 28

    x=222
    def f1():
        x=111
        def f2():
            # nonlocal x
            x=3
            print('f2---->',x) #f2----->  3
        f2()
        print('f1---->',x)  # f1------->  111
    
    f1()
    print('global------>',x)   #global------> 222
    

    无nonlocal结果

    图片 29图片 30

    x=222
    def f1():
        x=111
        def f2():
            nonlocal x
            x=3
            print('f2---->',x) #f2----->  3
        f2()
        print('f1---->',x)  # f1------->  3
    
    f1()
    print('global------>',x)   #global------> 222
    

    有nonlocal结果

     

    注意:

    图片 31图片 32

    六、装饰器

    a.暗中认可参数必须放在地点参数后边

    def mylen():
        """计算s1的长度"""
        s1 = "hello world"
        length = 0
        for i in s1:
            length = length 1
        return length
    
    str_len = mylen()
    print(str_len)
    

    黄金年代、闭包函数(函数体传值的新章程卡塔 尔(英语:State of Qatar)

      1、 -------->定义在函数内部的函数

      2、 -------->该内部函数包罗对其外层函数效能域名字的引用

    闭包函数平日需求结合函数对象的定义,将闭包函数重返到表面使用

    #闭包函数基本形式
    def outter():
        x=1
        def inner():
            print(x)
        return inner
    

    图片 33图片 34

    # 将值包给函数
    import requests  #导入爬虫模块
    # def outter(url):
    #     #url='https://www.jd.com'
    #     def get():
    #         response=requests.get(url)
    #         print(len(response.text))
    #     return get
    #
    # jd=outter('https://www.jd.com')#第一调用传入京东
    # jd()   #  以后调用只需要 jd加括号就能得到结果, 新的传值方式
    

    示范:闭包应用

    b.暗中同意参数平日定义成不可变类型

    回去三个值

    二、装饰器

      装饰指的是为被点缀对象增添新的职能

      指的工具

      装饰器自身是自由可以调用的靶子,被点缀对象也是随意能够调用的对象

    ps:写二个函数用来为另二个函数加多新功用,要求依照盛龙岩闭基准(对改革是查封的,对增加是开放的卡塔 尔(英语:State of Qatar)

      1、不更换被点缀对象的源代码

    函数进级,Python底蕴之函数。  2、不退换被点缀对象的调用情势

    图片 35图片 36

    import time
    
    def index():   #被装饰对象
        time.sleep(2)
        print('welcome to index page')
    #
    # index()  #原先功能
    def outter(func): #func=最原始index
        def wrapper():
            start_time=time.time()
            func()  #上方的index() 原先功能
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time)) #加入新功能
        return wrapper
    
    index=outter(index) #index=wrapper 加入新功能,并且调用方式没变
    index()
    

    装饰器的以身作则

    图片 37图片 38

    import time
    
    def home(name):  #有参
        time.sleep(1)
        print('welcome %s to home page' %name)
        return 'lalala'
    
    def timmer(func): #func=最原始index
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs) #原封不动转嫁参数
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res
        return wrapper
    
    
    home=timmer(home)  #home=warapper
    print(home('mogu'))
    

    被点缀对象有参

    c.暗许参数只在概念时被赋值一次

              2、再次回到多个值

    二、1、装饰器的语法糖  

      在被点缀对象正上方单唯生龙活虎行写上@装饰器名字

    图片 39图片 40

    import time
    
    def timmer(func): #func=最原始index
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res
        return wrapper
    
    
    @timmer #index=timmer(index)
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 'lalala'
    index()
    

    装饰器的语法糖!!

    图片 41图片 42

    import time
    
    current_userinfo={'user':None}
    
    def outter(func):
        def wrapper(*args,**kwargs):
            if current_userinfo['user']:
                return func(*args,**kwargs)
            user=input('please input you username: ').strip()
            pwd=input('please input you password: ').strip()
            if user == 'mogu' and pwd == '123':
                print('login successfull')
                # 保存登录状态
                current_userinfo['user']=user
                res=func(*args,**kwargs)
                return res
            else:
                print('user or password error')
    
        return wrapper
    
    @outter # index=outter(index)
    def index():
        print('welcome to index page')
        time.sleep(3)
    
    @outter #home=outter(home)
    def home(name):
        print('welecom %s ' %name)
        time.sleep(2)
        return 123
    
    index() # wrapper()
    res=home('mogu') # res=wrapper('mogu')
    

    注脚功用装饰器

    3卡塔 尔(阿拉伯语:قطر‎命名首要字参数:def register(*,name,age) *末尾定义的形参,必需被传值,且必须以主要字的样式传值

    5、函数的调用----接收重临值

    二、2、加多多少个装饰器

    图片 43图片 44

    import time
    
    current_userinfo={'user':None}
    
    def timmer(func): #func=最原始的index指向的内存地址
        def wrapper2(*args,**kwargs):
            print('wrapper2.....')
            start=time.time()
            res=func(*args,**kwargs) # func=最原始的index指向的内存地址
            stop=time.time()
            print('run time is %s' %(stop - start))
            return res
        return wrapper2
    
    def outter(func): # func=wrapper2
        def wrapper1(*args,**kwargs):
            print('wrapper1.....')
            if current_userinfo['user']:
                return func(*args,**kwargs)
            user=input('please input you username: ').strip()
            pwd=input('please input you password: ').strip()
            if user == 'mogu' and pwd == '123':
                print('login successfull')
                # 保存登录状态
                current_userinfo['user']=user
                res=func(*args,**kwargs) # func=wrapper2
                return res
            else:
                print('user or password err')
        return wrapper1
    
    
    # 解释语法的时候应该自下而上
    # 执行时则是自上而下
    # 可以连续写多个装饰器,处于最顶层的装饰器先执行
    @outter  # index=outter(wrapper2) # index=wrapper1
    @timmer # timmer(最原始的index指向的内存地址) ==>wrapper2
    def index():
        print('welcome to index page')
        time.sleep(3)
    
    index() #wrapper1()
    

    多个装饰器使用

    2.实参

       a、重返值为None    不收受

    二、3、有参数的装饰器

    图片 45图片 46

    import time
    
    current_userinfo={'user':None}
    
    def auth(engine='file'):#参数代表认证模式
        def outter(func): #func=最原始的index
            def wrapper(*args,**kwargs):
                if engine == 'file':#if判断认证模式
                    if current_userinfo['user']:
                        return func(*args,**kwargs)
                    user=input('please input you username: ').strip()
                    pwd=input('please input you password: ').strip()
                    if user == 'mogu' and pwd == '123':
                        print('login successfull')
                        # 保存登录状态
                        current_userinfo['user']=user
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('user or password err')
                elif engine == 'mysql':
                    print('mysql 的认证机制')
                    res = func(*args, **kwargs)
                    return res
                elif engine == 'ldap':
                    print('ldap 的认证机制')
                else:
                    print('不支持该engine')
            return wrapper
        return outter
    
    @auth(engine='mysql') #@outter # index=outter(最原始的index) # index= wrapper
    def index():
        print('welcome to index page')
        time.sleep(3)
    
    @auth(engine='ldap')
    def home(name):
        print('welecom %s ' %name)
        time.sleep(2)
        return 123
    
    index() #warpper()
    home('蘑菇') #wrapper('蘑菇')
    

    View Code

    1卡塔尔国地点实参:与岗位形参大器晚成意气风发对应

       b、重临值不为None

    二、4、wraps装饰器

      被点缀后的函数其实早已然是此外叁个函数了(函数名等函数属性会产生改换卡塔尔,为了不影响,Python的functools包中提供了三个叫wraps的decorator来杀绝这样的副成效。

    图片 47图片 48

    #wraps作用将被装饰对象属性赋值给 装饰器的wrapper
    import time
    from functools import wraps
    
    def timmer(func):
        @wraps(func)
        def wrapper(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' %(stop - start))
            return res
        # wrapper.__doc__ = func.__doc__
        # wrapper.__name__= func.__name__
        return wrapper
    
    @timmer
    def index():
        """
        这是一个index函数
        :return:
        """
        print('welcome to index page')
        time.sleep(1)
        return 123
    
    print(help(index)) # index.__doc__
    
    # print(index.__name__)
    

    wraps 装饰器

     

    2卡塔 尔(英语:State of Qatar)关键字参数:实参在概念时,依照key-values的花样定义

           1、再次来到叁个值

    七、表达式,生成式

     1、伊利表明式

      语法:【条件创建刻的重临值】   if 条件      else【条件不成马上的重回值】

    图片 49图片 50

    # res=条件成立时的返回值 if 条件 else 条件不成立时的返回值
    
    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    res=max2(1,2)
    
    x=10
    y=2
    
    res=x if x > y else y
    res=True if x > y else False
    print(res)
    

    安慕希表明式

      2、列表生成式

      语法: 【i】      for循环   可以跟 【条件】

    # 原先列表生成
    l=[]
    for i in range(10):
        if i > 3:
            l.append(i)
    print(l)
    #列表生成式
    l1=[i for i in range(10) if i > 3]  
    
    print(l1)
    

    图片 51图片 52

    #原先操作列表
    user=input('>>>:').strip()
    names=['hello world','hello dream','hello %s'%(user)]
    l=[]
    for name in names:
        if name.startswith('he'):
            l.append(name.upper())
    names=l
    print(names)
    #列表生成式操作
    user=input('>>>:').strip()
    names=['hello world','hello dream','hello %s'%(user)]
    names=[name.upper() for name in names if 
                  name.startswith('hello')]
    print(names)
    

    列表生成式:示例

     3、字典生成式

    图片 53图片 54

    info=[
        ['name','mogu'],
        ('age',18),
        ['sex','male']]
    #将列表转成字典:方法一
    d={}
    for item in info:
        d[item[0]] = item[1]
    print(d)
    
    #字典生成式   :方法二
    d={item[0]:item[1] for item in info}
    print(d)
    

    字典生成式

    图片 55图片 56

    d={
        'name':'蘑菇',
        'age':18,
        'sex':'male'
    }
    d={k.upper():v for k,v in d.items()}
    print(d)
    

    生成式改字典k的大大小小写

    语法:同列表同样   用到  for循环操作时事先构思生成式操作

     

      def foo(x,y)

                   用三个变量接收

    八、函数的递归调用

      在调用贰个函数的进程中又径直或直接的调用了本身。

    实为就是贰个再次的进度,必得有三个醒指标等级

      1、回溯:大器晚成层生机勃勃层地递归调用下去,每踏入风流浪漫层难题的局面都应有具有减小

      2、递推:递归必需有一个简来说之的扫尾条件,在满意该准则的景观下甘休递归,往回生机勃勃层风流浪漫层地终结调用

    图片 57图片 58

    #询问年龄,第一个人说我比第二个人大2岁,第二个人说我比第三个人大2岁,。。。第六个人说“我18岁”
    # age(6) = age(5)   2
    # age(5) = age(4)   2
    # age(4) = age(3)   2
    # age(3) = age(2)   2
    # age(2) = age(1)   2
    # age(1) = 18
    
    # age(n) = age(n-1)   2 #n > 1
    # age(n) = 18           #n=1
    #
    
    def age(n):
        if n == 1:   #结束条件
            return 18
        return age(n-1)   2  #基于上一次的结果调用自己
    
    print(age(6))
    

    示例1

    图片 59图片 60

    #  将一个列表中包含的值全部取出
    l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
    
    def tell(l):
        for item in l:
            if type(item) is list:
                #item 是列表
                # 再次调用本身的逻辑,传入item
                tell(item)
            else:
                #item是单独的元素
                print(item)
    
    tell(l)
    

    示例2

    图片 61图片 62

    #数字列表,数字是从小到大排列的
    nums=[3,11,13,15,23,27,43,51,72,81,93,101]
    
    #算法:就是如何高效地解决某一个具体问题的方法
    l1=[3,11,13,15,23,27]
    l2=[23,27]
    l3=[23]
    
    def binary_search(nums,find_num):
        print(nums)
        if len(nums) == 0:
            print('not exists')
            return
        mid_index=len(nums) // 2
        if find_num > nums[mid_index]:
            # in the right
            nums=nums[mid_index 1:]
            # 重复调用本身的逻辑,传入新的nums
            binary_search(nums,find_num)
    
        elif find_num < nums[mid_index]:
            # in the left
            nums=nums[:mid_index]
            # 重复调用本身的逻辑,传入新的nums
            binary_search(nums,find_num)
        else:
            print('find it')
    
    binary_search(nums,94)
    

    函数的递归调用 二分法

      foo(x=1,y=2)

           2、再次来到多少个值

    九、佚名函数

      无名函数lambda:有时用二遍之后不再行使了。

    #格式:
    def sum2(x,y):
        return x   y
    print(sum2)
    
    sum2=lambda x,y:x   y
    
    wage={
        'I':3800,
        'BOSS':9999999,
        'friends':10000,
        'web celebrity':1000000
    }
    
    print(max(wage,key=lambda x:wage[x]))#匿名函数使用场景 最大
    print(min(wage,key=lambda x:wage[x]))#最小
    
    # 按照薪资高低排序人名
    print(sorted(wage,key=lambda x:wage[x])) #从小到大
    
    print(sorted(wage,key=lambda x:wage[x],reverse=True))#翻转
    

      关键字参数能够毫不向地方参数同样与形参大器晚成生龙活虎对应,能够打破顺序节制

                   a、用三个变量选用,选拔的结果是三个元祖

    十、迭代器,生成器,生成器表明式

    瞩目:a.地方参数和要害字参数混合使用的时候,地方参数必得在重大字参数前边

                   b、有多少个重临值就用略带个值选用

     1、迭代器

      迭代器便是迭代取值的工具

      迭代是三个重复的历程,但是每三次重复都以依照上叁次的结果而开展

    迭代器的效用:针对一向不索引的数据类型,比方(字典、会集、文件卡塔 尔(阿拉伯语:قطر‎想要迭代抽出此中含有的值

           python解释器提供了后生可畏种不信赖索引取值的工具

    # 可迭代的对象:在python中但凡内置有__iter__方法的对象都称之为可迭代对象
      (字符串、列表、元组、字典、集合、文件)
    

    图片 63图片 64

    str1 = 'hello'
    list1 = ['a', 'b', 'c']
    t1 = ('a', 'b', 'c')
    dic = {'x': 1, 'y': 2}
    set1 = {'m', 'n'}
    f = open('a.txt', mode='rt', encoding='utf-8')
    

    可迭代对象

     

    # 迭代器对象:
    # 1、内置有__iter__方法,调用迭代器对象的__iter__方法得到仍然是迭代器本身
    # ps: 文件对象本身就是一个迭代器对象
    # 2、内置有__next__方法
    
    dic = {'x': 1, 'y': 2}
    
    iter_dic = iter(dic)   # iter_dic=dic.__iter__()
    #上面得到迭代器对象 iter_dic
    
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    #就可以调__next__方法取值
    

    图片 65图片 66

    dic={'x':1,'y':2}
    iter_dic=iter(dic) # 调__iter__得到迭代器
    
    while True:
        try:      #检测异常
            k=next(iter_dic)    #执行__next__取值
            print(k)
        except StopIteration:  #接try 的检测   
            break
    
    -----------------------------------------------------------------
    #上述即为  for循环的   底层原理
    

    for循环运行机制!!

       b.不仅可以够是岗位实参格局,也得以是重视字实参方式,不过二个形参只可以传值一回

    6、参数

    总结:

    迭代器的长处:
      意气风发、提供了黄金年代种能够不信赖索引的、通用的迭代取值格局
        补充:for循环能够称呼迭代器循环

     list1=['a','b','c']
        for item in list1:
        print(item)
    

        for循环的做事流程
       1、调用 in 后边那个目的的__iter__艺术,得到多少个迭代器对象
       2、调用迭代器对象的__next__措施,拿到多个重回值赋值给变量名item
       3、周而复始,直到抛出分外,for循环会自动捕捉非凡停止循环

      二、节本省部存款和储蓄器

    迭代器的先天不足:
      1、针对同一个迭代器对象只可以取完三次,不比遵照索引也许key取值形式灵活
      2、无法预测迭代器对象所包涵值的个数

     

    3卡塔 尔(阿拉伯语:قطر‎可变长参数:

        a、参数----站在概念函数的角度

    2、生成器

    在函数内但凡现身yield 关键字,在调用函数就不会触发函数体代码的实行了,

    会获取二个重回值,再次来到值正是二个生成器对象

    而生成器对象本质就是迭代器(ps:生成器是自定义的迭代器卡塔尔国

    def foo():
        print('first')
        yield 1
        print('second')
        yield 2
        print('third')
        yield 3
        print('fourth')
    
    g=foo() #g是生成器=》就是迭代器
    g.__next__()
    g.__next__()
    g.__next__()
    

    上述会触发g对应的函数体代码的实施,直到遭受四个yield就一噎止餐住,该yield后的值作为此次__next__的再次来到值再次来到

    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    

      按岗位定义的可变长参数用*表示

             1、地点参数

    总结yield的功能:

    1、提供了朝气蓬勃种自定义迭代器的点子

    2、能够用于再次来到值

      yield和return的区别:

        相似点:都得以用来重临值,个数以至项目都未有范围

        分裂点:yield能够回来多次值,return只好回到三遍值整个函数就甘休了

    3、函数暂停以至继续执行之处是由yield保存的

    def my_range(start,stop,step=1):
        while start < stop: # 4 < 4
            yield start #start = 3
            start =step #star=4
    #----------------------------------------------------------
    #range()的原理
    
    for i in my_range(1,5): # 1  3
        print(i)
    

    了解:yield关键字表明式方式的使用

    图片 67图片 68

    def cat(name):
        print('橘猫[%s]准备开吃' %name)
        food_list=[]
        while True:
            food=yield food_list#food=yield='鱼干'
            print('橘猫[%s]吃了: %s' %(name,food))
            food_list.append(food)
    #
    ct=cat('蘑菇')
    
    # 强调:针对表达式形式的yield,在使用生成器时必先send(None),相当于先完成一个初始化操作
    res0=next(ct) #ct.send(None)
    # print(res0)
    
    #send有两个功能:
    #1、为当前暂停位置的yield赋值
    #2、与next的效果一样
    ct.send('鱼干')
    # next(ct)
    # ct.send(None)
    ct.send('三鹿')
    res1=ct.send('鱼干')
    # print(res1)
    res2=ct.send('牛奶')
    print(res2)
    

    yield关键字表达式

     

      按主要性字定义的可变类型的参数用**表示  

             2、私下认可参数

     3、生成器表明式

     同上述列表、字典生成式同样的款式,只是两侧换来了()

    l=[i**2 for i in range(1,11)]
    print(l)###列表生成式
    #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    #==================================
    l1=(i**2 for i in range(1,11))
    print(l1)
    #<generator object <genexpr> at 0x0000000001EC05C8>
    #()括号生成了一个迭代器对象,只要不调用l1,其内部就没有值,调一次next方法就取出一个值
    print(next(l1))
    

    优点是:

      越发节约内部存款和储蓄器

      自定义迭代器的点子

     

    def func(x,y,*args):
        print(x,y,args)
    func(1,2,3,4,5)  --->1 2 (3 4 5)
    

             3、动态参数

    十风度翩翩、面向进程编制程序

    图片 69图片 70

    #=============复杂的问题变得简单
    #注册功能:
    #阶段1: 接收用户输入账号与密码,完成合法性校验
    def talk():
        while True:
            username=input('请输入你的用户名: ').strip()
            if username.isalpha():
                break
            else:
                print('用户必须为字母')
    
        while True:
            password1=input('请输入你的密码: ').strip()
            password2=input('请再次输入你的密码: ').strip()
            if password1 == password2:
                break
            else:
                print('两次输入的密码不一致')
    
        return username,password1
    
    #阶段2: 将账号密码拼成固定的格式
    def register_interface(username,password):
        format_str='%s:%sn' %(username,password)
        return format_str
    
    #阶段3: 将拼好的格式写入文件
    def handle_file(format_str,filepath):
        with open(r'%s' %filepath,'at',encoding='utf-8') as f:
            f.write(format_str)
    
    
    def register():
        user,pwd=talk()
        format_str=register_interface(user,pwd)
        handle_file(format_str,'user.txt')
    
    
    register()
    

    面向进程编程

    #1、首先强调:面向过程编程绝对不是用函数编程这么简单,
        面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。
        言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序
    
    #2、定义
    面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么
    
    基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式
    
    #3、优点:复杂的问题流程化,进而简单化
    
    #4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身
    
    #5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd
    
    #6、举例
    流水线1:
    用户输入用户名、密码--->用户验证--->欢迎界面
    
    流水线2:
    用户输入sql--->sql解析--->执行功能
    

       写于:2018-08-27   15:42:22 

    #遇到*纵然地方参数,把*前边的整个拆开,再大器晚成意气风发相配,多余的就以元组的样式存放到手拉手

                  a、*args

    def func(x,y,**kwargs):
        print(x,y,kwargs)
    func(1,y=2,z=3,a=1,b=2)---->1 2 {'z': 3, 'a': 1, 'b': 2}
    

                  b、**kwargs

    #遇到**就算重视字参数,把**末端的总体拆成最首要字,再意气风爆发机勃勃相称,多余的以字典方式贮存到联合

    各样:地点参数、*args、暗中同意参数、**kwargs

    def wrapper(*args,**kwargs):能够承担率性情势,大肆长度的参数

         b、参数----站在调用函数的角度上

    参数的概念顺序:x,y=1,*args,z,**kwargs,分别是岗位参数,暗许参数,可变长地方参数,命名第一字参数,可变类型参数

             1、依照职位传参

    但供给专心的是,这几个参数并不会同期全体涌出

             2、依据注重字传参

    三、名称空间和功用域

             3、动态传参*tup,**dic

    名称空间寄存名字和值的绑定关系,以key-value 的格局

    7、参数分为形参和实参   

    在Windows命令提醒行中输入指令:import this ,在结尾大器晚成行会看出那样一句话:

         a、实参:调用函数的时候传出的参数

      Namespaces are one honking great idea -- let's do more of those!

    8、地点参数

    名称空间分为三种:

         a、地方参数务必传值

    1卡塔尔内置名称空间:Python自带的,如print,int,len....当Python解释器运转的时候,就能够变动内置名称空间

    图片 71图片 72

    2卡塔 尔(英语:State of Qatar)全局名称空间:文件等第定义的名字会寄放到全局名称空间,推行Python程序的时候发出,简单题说哪怕从未缩进的变量名

    def aaa(a,b):
        print(a,b)
    aaa(1,2)
    

    3卡塔 尔(阿拉伯语:قطر‎局地名称空间:定义在函数(或模块、类卡塔 尔(阿拉伯语:قطر‎内部的名字,独有在函数(模块、类卡塔尔国调用的时候才生效,调用甘休后就能够释放

    职责参数

    加载顺序是:内置名称空间-->全局名称空间-->局地名称空间

    9、暗中同意参数

    取值顺序是:局地名称空间-->全局名称空间-->内置名称空间

         a、默许参数能够不传值

    四、函数嵌套和作用域

    图片 73图片 74

    1.函数嵌套蕴含函数的嵌套调用和函数的嵌套定义

    def bbb(x=10):
        print(x)
     bbb()     #x = 10
     bbb(20)  #x = 20
    

    函数嵌套调用能够用求最大值的例子来注解:

    暗中认可参数

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    def max4(a,b,c,d):
        res1=max2(a,b) #23
        res2=max2(res1,c) #23
        res3=max2(res2,d) #31
        return res3
    
    print(max4(11,23,-7,31))
    

    10、动态参数

    函数嵌套定义:

    图片 75图片 76

    def f1():
        def f2():
            def f3():
                print('from f3')
            print('from f2')
            f3()
        print('from f1')
        f2()
    # print(f1)
    f1()
    
    def ccc(*args):#1,2,3,4,5
        print(args)
    
    ccc(1,2,3,4,5)#按位置传参数
    
    t = (1,2,3,4,5)
    ccc(t)  ((1, 2, 3, 4, 5),)
    ccc(*t)  (1, 2, 3, 4, 5)
    复制代码
    

    2.作用域

    动态参数

    1卡塔 尔(英语:State of Qatar)全局作用域:内置名称空间与全局名称空间的名字归属全局范围,在任何文件的自由地方都能援用

    图片 77图片 78

    2卡塔 尔(英语:State of Qatar)局地效能域:归于某个范围,只在函数内部能够被引用,局地有效

    def ddd(**kwargs):
        print(kwargs)
    
     ddd(k = 'a',j = 'b')#按关键字传参数
    

    一定要留心局地变量和全局变量的效果与利益范围,在生龙活虎部分更正全局变量会出错,在大局范围引用局地变量也会出错

    动态参数 关键字参数

    成效域在函数定义时就早就固定了,不会因调用地方而退换

    图片 79图片 80

    然而假设应当要在生龙活虎部分改过全局变量,也是用艺术的,便是在要改正的变量前加三个global

    def eee(*args,**kwargs):
        print(args,kwargs)
    
     eee(12,123)
    
    x=1
    def foo():
        x=10
        print(x)        
    
    foo()       #10
    print(x)    #1
    
    x=1
    def foo():
        global x
        x=10
        print(x)
    
    foo()       #10
    print(x)    #10
    
    def foo():
        x=1
        def f2():
            x =x
            return x
        return f2()
    
    print(foo())        #会报错UnboundLocalError: local variable 'x' referenced before assignment
    
    def foo():
        x=1
        def f2():
            nonlocal x  #告诉Python解释器,这里的x不是局部变量,只会找函数内部的,不会修改全局变量
            x =x
            return x
        return f2()
    
    print(foo())    #会打印出修改后的x的值,2
    

    动态,先按职责参数,再按重要性字参数

    五、闭包函数

    11、命名空间

    概念在函数内部的函数,该内部函数包涵对表面作用域,而非全局成效域的名字的引用,那么该内部函数称为闭包函数

         a、命名空间分为两种

    name='egon'
    def func():
        name='alex'
        def bar():
            print(name)
        return bar
    
    f=func()        #f就是闭包函数
    print(f.__closure__[0].cell_contents)       #该命令可以查看闭包函数外面包了什么东西------>alex
    

                1、全局命名空间

    闭包函数的表征:a.自带成效域,b.延迟计算(f只是获得了函数的内部存款和储蓄器地址,何时用,加括号就能够运营卡塔尔国

                2、局地命名空间

    闭包函数最主旨的样式:

                3、内置命名空间

    def 外界函数名(卡塔尔:

         b、二种命名空间的风流洒脱大器晚成:内置命名空间>全局命名空间>局地命名空间

      内部函数必要的变量

         c、取值

      def 内部函数名(卡塔尔:

               1、在有的调用:局地命名空间->全局命名空间->内置命名空间

        援用外界变量

    图片 81图片 82

      return 内部函数名

    x = 1
    def f(x):
        print(x)
    
    print(10)
    

    六、装饰器

    View Code

    1.开花封闭原则:对扩张是开放的,对订正是密闭的

              2、在全局调用:全局命名空间->内置命名空间

    2.装饰器本质是随便可调用的对象,被点缀对象也是轻松可调用的目的

    图片 83图片 84

    3.装饰器的成效是:在不更改被点缀对象源代码及调用方式的前提下,为其增添新的效益

    x = 1
    def f(x):
        print(x)
    
    f(10)
    print(x)
    

    4.装饰器语法:在被装饰对象的正上方的单身风姿浪漫行,写上@装饰器名字

    View Code

    5.有多少个装饰器的时候,每行三个,试行时从上往下运作

    12、作用域

    6.被装饰函数有参数的图景:写成(*args,**kwargs)的形式

          a、  效用域正是效果与利益范围,遵照生效范围能够分成全局作用域和部分效用域。

    装饰器示例黄金年代:

          b、  全局功效域:蕴含放到名称空间、全局名称空间,在全部文件的人身自由地点都能被引用、全局有效

    #实现缓存网页内容的功能,下载的页面存放于文件中,如果文件内有值(文件大小不为0),
    # 就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
    from urllib.request import urlopen
    import os
    
    cache_path=r'C:untitled615Python第8天cache_file.txt'
    def make_cache(func):
        def wrapper (*args,**kwargs):
            if os.path.getsize(cache_path):
                #有缓存
                print('33[45m========>有缓存33[0m')
                with open(cache_path,'rb') as f:
                    res=f.read()
            else:
                res=func(*args,**kwargs)#下载
                with open(cache_path,'wb') as f:#制作缓存
                    f.write(res)
            return res
        return wrapper
    
    
    @make_cache
    
    def get(url):
        return urlopen(url).read()
    
    
    print(get('https://www.python.org'))
    

          c、局地功用域:局地名称空间,只好在部分范围生效

    装饰器示例二:

    作用域:
    小范围的可以用大范围的
    但是大范围的不能用小范围的
    范围从大到小(图)
    在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
    如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
    如果都没有,报错
    
    #为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
    db_dic={
        'egon':'123',
        'alex':'alex3714',
        'yuanhao':'smallb'
    }
    
    
    db_path=r'C:untitled615Python第8天db_dic.txt'
    
    with open(db_path,'w',encoding='utf-8') as f:
        f.write(str(db_dic))
    
    login_dic={
        'user':None,
        'status':False,
    }
    
    def auth(func):
        def wrapper(*args,**kwargs):
    
            #加一个验证状态的字典,如果已经登录成功,下次使用就不用重新验证
            if login_dic['user'] and login_dic['status']:
                res=func(*args,**kwargs)
                return res
            else:
                name=input('name:')
                password=input('password:')
                with open(db_path, 'r', encoding='utf-8') as f:
                    auth_dic = eval(f.read())
                if name in auth_dic and password==auth_dic[name]:
                    print('login ok')
                    login_dic['user']=name
                    login_dic['status']=True
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('error')
        return wrapper
    
    @auth
    def index():
        print('welcom to the page')
    
    @auth
    def home(name):
        print('welcom  to %s's home page'%name)
    
    
    index()
    home('egon')
    

    13、闭包

    七、迭代器

           a、闭包分为:

    1.对此字符串、列表、元组的数据类型,我们得以依附索引来实现迭代的成效,可是字典、会集这种未有索引的数据类型,就须求其余情势

                1、闭:内部函数

    2.Python为了提供生机勃勃种不依赖索引的迭代情势,为局地对象放置了__iter__方法,obj.__iter__()拿到的结果便是迭代器

                2、包:包涵对表面函数的成效域中变量的援引

    获得的迭代器既有.__iter__方法,又有.__next__方法

           b、闭包常用的的情势

    3.迭代器的亮点:

    图片 85图片 86

      a.提供了豆蔻年华种不相信赖索引的取值情势

    def hei():
        x = 20
        def inner():
            print(x)  #局部的
        return inner
    
    i = hei()
    i()  #全局
    

      b.惰性总结,节本省部存储器

    闭包常用情势

    4.迭代器的弱项:

    14、函数值装饰器

      a.取值比不上遵照索引取值方便

          a、装饰器的真面目:闭包函数

      b.三遍 性的,取值只可以以后走,无法往前退

          b、装饰器的效果与利益:正是在不退换原函数调用形式的图景下,在这里个函数的上下加上扩充作用

      c.无法获取迭代器的尺寸

    图片 87图片 88

    5.for循环其实会默许调用.__iter__方法

    def timer(func):
        def inner(a):
            start = time.time()
            func(a)
            print(time.time() - start)
        return inner
    
    @timer
    def func1(a):
        print(a)
    
    func1(1)
    

    6.料定是还是不是是可迭代对象和迭代器,能够用命令

    带参数的装饰器

    print(isinstance(str1,Iterable)) --->判断是还是不是为可迭代对象

    15、装饰器的绽龙岩闭原则:

    print(isinstance(str1,Iterator)) --->决断是或不是为迭代器

          a、对扩张是开放的

    八、生成器函数(语句形式和表明式方式卡塔尔

          b、对纠就是查封的

    1.生成器函数:函数体内蕴涵有yield关键字,该函数的实施结果正是生成器

    图片 89图片 90

    2.生成器实际正是迭代器的风流洒脱种

    def timer(func):
        def inner(*args,**kwargs):
            '''执行函数之前要做的'''
            re = func(*args,**kwargs)
            '''执行函数之后要做的'''
            return re
        return inner
    

    3.yield的功能:

    装饰器的长久方式

    *  a.与return雷同,都能够再次回到值,但不等同的地点在于yield重临数十次值,而return只好回到一回值
      b.为函数封装好了__iter__和__next__方法,把函数的实行结果做成了迭代器
      c.遵从迭代器的取值格局obj.__next__(卡塔尔,触发的函数的施行,函数暂停与再持续的场馆都是由yield保存的
    4.生成器讲话形式利用实例*

    16、装饰器应用途景

    图片 91图片 92

          a、总括func的奉行时间

     1 #模拟linux中tail -f a.txt|grep 'error' |grep '404'的功能
     2 import time
     3 def tail(filepath,encoding='utf-8'):
     4     with open(filepath,encoding='utf-8') as f:
     5         f.seek(0,2)  #以末尾为开始位,第0个
     6         while True:
     7             line=f.readline()
     8             if line:
     9                 yield line
    10             else:
    11                 time.sleep(0.5)
    12 
    13 def grep(lines,pattern):
    14     for line in lines:
    15         if pattern in line:
    16             # print(line)
    17             yield line
    18 
    19 g1=tail('a.txt')
    20 g2=grep(g1,'error')
    21 g3=grep(g2,'404')
    22 
    23 for i in g3:
    24     print(i)
    

          b、登入认证

    View Code

    17、可迭代

    5.生成器的表明式情势

          a、字符串,列表,集结,字典,元祖那一个度能够for循环,表达她们是可迭代的

    def foo():
        print('starting')
        while True:
            x=yield #默认就是yield None
            print('value :',x)
    
    g=foo() 
    next(g)  #初始化,等同于g.send(None)
    g.send(2)  
    

          b、迭代正是:将有些数据集内的数量二个挨三个的抽出来,就 叫做可迭代

    将yield赋值给三个变量如x=yield,然后用send()传值,但只顾要先做三个看似发轫化的操作

          c、可迭代对应标识:__iter__

    g.send(2)的操作实际是先把2传值给yield,再由yield传值给x,send()既有传值的功能,又有next()的功用

    18、迭代交涉

    生成器表明式情势利用示范

          a、但愿以此数据类型里的事物也能够利用for被二个八个的抽出来,那大家就亟须满足for的供给

    图片 93图片 94

          b、可迭代公约——凡是可迭代的当中都有叁个__iter__方法

     1 def init(func):
     2     def wrapper(*args,**kwargs):
     3         g=func(*args,**kwargs)
     4         next(g)
     5         return g
     6     return wrapper
     7 @init
     8 def eater(name):
     9     print('%s ready to eat' %name)
    10     food_list=[]
    11     while True:
    12         food=yield food_list#return None
    13         food_list.append(food)
    14         print('%s start to eat %s' %(name,food))
    15 
    16 
    17 e=eater('alex')
    18 print(e.send('狗屎'))
    19 print(e.send('猫屎'))
    20 print(e.send('alex屎'))
    21 
    22 
    23 def make_shit(people,n):
    24     for i in range(n):
    25         people.send('shit%s' %i)
    26 
    27 e=eater('alex')
    28 make_shit(e,5)
    29 #from egon
    30 #egon老师的例子有味道,但是我又忍不住不用这个
    

    19、迭代器合同

    View Code

          a、迭代器合同 : 内部贯彻了__iter__ __next__方法

    九、伊利表明式

     可迭代和迭代器的区别点 : 迭代器多完毕了三个__next__方法

    res= x if x>y else y----->度量标准x>y是还是不是为真,为真则把x赋给res,不然把y赋给res

     可迭代和迭代器的相近点 : 都足以用for循环

    十、列表深入分析

    20、推断迭代器和可迭代的方法 

    s='hello'
    res=[i.upper() for i in s]
    print(res)          #['H', 'E', 'L', 'L', 'O']
    

           a、第风姿浪漫种:推断在这之中是或不是兑现了 __next__** **

                               '__next__' in dir(o)

           b、第二种

    from collections import Iterable  #可迭代
    from collections import Iterator  #迭代器
    isinstance(o,Iterable)
    isinstance(o,Iterator)
    

    21、生成器

          a、生成器函数:常规函数定义,但是,使用yield语句实际不是return语句重临结果。yield语句叁次回到叁个结果,在各样结果中间,

              挂起函数的场合,以便下一次重它离开的地点继续实行

          b、生成器说明式:近似于列表推导,可是,生成器重返按需发生结果的一个对象,实际不是叁回创设二个结实列表**

    生成器函数

    图片 95图片 96

    def func():
        print('aaaa')
        a = 1
        yield a    #返回第一个值
        print('bbbb')
        yield 12   #返回第二个值
    ret = func()  #拿到一个生成器
    print(ret)
    print(next(ret)) #取第一个值
    print(next(ret)) #取第二个值
    print(next(ret)) #取第三个值 会报错 因为没有第三个值
    

    生成器函数

    22、列表推导式

    平常:

    图片 97图片 98

    for i in range(100):
        print(i*i)
    

    n*n

    列表推到:

    图片 99图片 100

    l =[i*i for i in range(100)]
    print(l)
    

    n*n

    23、递归函数

         a、在一个函数里调用自身

         b、Python递归最大层数约束997

         c、最大层数限定是python暗中认可的,能够做改正,不过不建议您改改

         d、递归实例

    图片 101图片 102

    def age(n):
        if n == 1:
            return 40
        else:
            ret = age(n-1)
            return ret   2
    age(5)
    

    算年龄

         e、递归甘休标记:return

    递归三级菜单

    图片 103图片 104

    menu = {
        '北京': {
            '海淀': {
                '五道口': {
                    'soho': {},
                    '网易': {},
                    'google': {}
                },
                '中关村': {
                    '爱奇艺': {},
                    '汽车之家': {},
                    'youku': {},
                },
                '上地': {
                    '百度': {},
                },
            },
            '昌平': {
                '沙河': {
                    '老男孩': {},
                    '北航': {},
                },
                '天通苑': {},
                '回龙观': {},
            },
            '朝阳': {},
            '东城': {},
        },
        '上海': {
            '闵行': {
                "人民广场": {
                    '炸鸡店': {}
                }
            },
            '闸北': {
                '火车战': {
                    '携程': {}
                }
            },
            '浦东': {},
        },
        '山东': {},
    }
    
    def threeLM(menu):
        for key in menu:
            print(key)
        k = input(">>>")
        if k in menu:
            threeLM(menu[k])
    
    threeLM(menu)
    

    三级菜单

    24、无名氏函数

         a、 无名函数 轻巧的急需用函数去清除的问题 无名函数的函数体 独有大器晚成行,也叫lambda

         b、 函数名 = lambda 参数 :返回值

         c、参数能够有四个,用逗号隔离,佚名函数不管逻辑多复杂,只可以写后生可畏行,且逻辑实施实现后的剧情正是重临值。重临值和健康的函数相近能够是自由数据类型

    图片 105图片 106

    add2 = lambda x,y : x y
    ret = add2(1,2)
    print(ret)
    

    View Code

    图片 107图片 108

    l = [1,2,3,4]
    print(list(map(lambda x:x*x , l)))
    

    View Code

    图片 109

    25、内置函数

        a、isinstance  剖断变量的数据类型

    temp = "asdfsdfs"  
    
    r = isinstance(temp, list)  
    
    print(r)
    

        b、lambda用法:

    def f1():  
    
        return 123  
    
    f2 = lambda :123  
    
    r1 = f1()  
    
    r2 = f2()  
    
    print(r1,r2)
    
    def f3(a1,a2):  
    
        return a1   a2  
    
    f4 = lambda a1,a2: a1   a2  
    
    r3 = f3(1,2)  
    
    r4 = f4(3,4)  
    
    print(r3,r4) 
    

        c、abs--取相对值

    i = abs(-123)  
    
    print(123)
    

        d、divmod  除商得余数---举例分页

    a = 10 / 3  
    
    print(a)  
    
    r = divmod(10,3)  
    
    print(r)  
    
    结果:  
    
    3.33333335  
    
    (3,1) 
    

       e、eval  -----强制不转移输入类型的格式

    ret = eval("1   3")  
    
    print(ret)  
    
    结果:4 
    

       f、filter (过滤)

    ret = filter(lambda x: x >22, [11,22,33,44])  
    
    for i in ret:  
    
        print(i)
    

      g、map  无论是map照旧filter,得到的结果都以可迭代的对象,迭代器的实例

    def f1(x):  
    
        if x % 2 == 1:  
    
           return x   100  
    
        else:  
    
           return x  
    
    ret = map(f1, [1,2,3,4,5])  
    
    ret2 = map(lambda x: x   100if x % 2 == 1 else x ,[1,2,3,4,5])  
    
    print(ret)  
    
    for i in ret :  
    
        print(i) 
    

       h、max()最大数 min()  最小数

    li = [11,22,123,1]  
    
    r = max(li)  
    
    print(r)  
    
    a = min(li)  
    
    print(a) 
    

       g、pow(x,y) ----就是求x的y次方

    i = pow(2,100)  
    
    print(i) 
    

       k、zip ---意思正是取三个变量中索引相对应的值

    li1 = [11,22,33,44]  
    
    li2 =["a",'VV',"c","E"]  
    
    r = zip(li1,li2)  
    
    print(r)  
    
    for i in r :  
    
        print(i)
    

      l、、open---打开,关闭,close

    模式    描述
    r      打开一个文件为只读。文件指针被放置在文件的开头。这是默认模式。
    rb     打开一个文件只能以二进制格式读取。文件指针被放置在文件的开头。这是默认模式。
    r      打开用于读和写文件。文件指针置于该文件的开头。
    rb     打开用于读取和写入二进制格式的文件。文件指针置于该文件的开头。
    w      打开一个文件只写。如果文件存在覆盖该文件。如果该文件不存在,则创建写入新文件。
    wb     打开一个文件只能以二进制格式写入。如果文件存在覆盖该文件。如果该文件不存在,则创建写入新文件。
    w      打开文件为写入和读取模式。如果文件存在覆盖现有文件。如果该文件不存在,创建用于读写操作的新文件。
    wb     打开用于以二进制格式写入和读出文件。如果文件存在覆盖现有文件。如果该文件不存在,创建用于读写操作的新文件。
    a      打开用于追加的文件。文件指针是在文件是否存在该文件的末尾。也就是说,该文件是在追加模式。如果该文件不存在,它会创建一个用于写入的新文件。
    ab     打开文件用于二进制格式追加。文件指针是在文件是否存在该文件的末尾。也就是说,文件是在追加模式。 如果该文件不存在,它会创建一个用于写入的新文件。
    a      打开文件为追加和读取方式。文件指针是在文件是否存在该文件的末尾。该文件以追加模式打开。如果该文件不存在,它将创建用于读写操作的新文件。
    ab     打开一个文件以附加和二进制格式读取模式。如果该文件存在文件指针在该文件的末尾。该文件以追加模式打开。如果该文件不存在,它将创建读写操作的新文件。
    

     

     

     

     

     
    

     

            

     

     

       

     

     

     

           

     

       

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:函数进级,Python底蕴之函数

    关键词:

上一篇:新葡亰496net:排序算法,Python实现链表

下一篇:没有了