zoukankan      html  css  js  c++  java
  • 函数

    函数的基本使用

    1、什么是函数?   

    在程序中,函数就具备某一功能的工具

    事先将工具准备好即函数的定义

    遇到应用场景拿来就用即函数的调用

    所以务必记住:#函数的使用必须遵循先定义,后调用的原则

    2、为何要用函数

     不用函数问题是:

     1、程序冗长

     2 程序的扩展性差

     3 程序的可读性差

    3 如何用函数:

      函数的使用必须遵循先定义,后调用的原则

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

         函数功能的描述信息

         :param 参数1: 描述

         :param 参数2: 描述

         :return: 返回值

         '''

         代码1

         代码2

         代码3

         ...

         return 返回值

    函数的分类

    1、内置函数
    为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
    ps:我们将会在最后详细介绍常用的内置函数。
    
    2、自定义函数
    很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。



    什么时候该有返回值?
        调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
        通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果

    什么时候不需要有返回值?     调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值     通常无参函数不需要有返回值

     准备好工具=>函数的定义阶段

    def register():

        while True:

            uname=input('username>>:').strip()

            if uname.isalpha():

                break

            else:

                print('用户名必须由字母组成傻叉')

        while True:

            pwd1=input('密码>>: ').strip()

            pwd2=input('重复输入密码>>: ').strip()

            if pwd1 == pwd2:

                break

            else:

                print('两次输入的密码不一致,眼瞎吗')

        with open('db.txt','at',encoding='utf-8') as f:

            f.write('%s:%s ' %(uname,pwd1))

            f.flush()

    def auth():

        #认证功能

        inp_uname=input('请输入你的账号:').strip()

        inp_pwd=input('请输入你的密码:').strip()

        with open('db.txt','rt',encoding='utf-8') as f:

            for line in f:

                info=line.strip(' ').split(':')

                if inp_uname == info[0] and inp_pwd == info[1]:

                    print('login successfull')

                    break

            else:

                print('账号或密码错误')

     拿来就用=>函数的调用阶段

     print(register)

     register()

     auth()

     register()

     register()

     register()

    函数的定义阶段和调用阶段

     函数的使用必须遵循先定义,后调用的原则,

     没有事先定义函数,而直接引用函数名,就相当于在引用一个不存在的变量名

    1、函数定义阶段:只检测函数体的语法,不执行函数体代码

     def func():

         print('1111')

         print('222')

         print('333')

    2、函数调用阶段:执行函数体代码

     func()

     例1

     def foo():

         print('from foo')

         bar()

     foo()

     例2

     def bar():

         print('from bar')

     def foo():

         print('from foo')

         bar()

     foo()

     例3

     def foo():

         print('from foo')

         bar()

     def bar():

         print('from bar')

     foo()

     例4

     def foo():

         print('from foo')

         bar()

     foo()

     def bar():

         print('from bar')

    函数的定义

    定义函数时的参数就是函数体接收外部传值的一种媒介,其实就一个变量名

    1、无参函数:

     在函数定义阶段括号内没有参数,称为无参函数

     注意:定义时无参,意味着调用时也无需传入参数

     应用:

    如果函数体代码逻辑不需要依赖外部传入的值,必须定义无参函数

     def func():

         print('hello world')

     func()

    2、有参函数

     在函数定义阶段括号内有参数,称为有参函数

     注意:定义时有参,意味着调用时也必须传入参数

     应用:

    如果函数体代码逻辑需要依赖外部传入的值,必须定义成有参函数

     def sum2(x,y):

         # x=10

         # y=20

         res=x+y

         print(res)

     sum2(10,20)

     sum2(30,40)

    def check_user():

        while True:

            uname=input('username>>:').strip()

            if uname.isalpha():

                return uname

                # break

            else:

                print('用户名必须由字母组成傻叉')

    def check_pwd():

        while True:

            pwd1=input('密码>>: ').strip()

            pwd2=input('重复输入密码>>: ').strip()

            if pwd1 == pwd2:

                return pwd1

            else:

                print('两次输入的密码不一致,眼瞎吗')

    def db_hanle(uname,pwd1):

        with open('db.txt','at',encoding='utf-8') as f:

            f.write('%s:%s ' %(uname,pwd1))

            f.flush()

    def register():

        # 检测用户名是否合法

        x=check_user() #x='EGON'

        # 检测密码是否合法

        y=check_pwd() #y='123'

        # 写入数据文件

        # db_hanle(合法的用户名,合法的密码)

        db_hanle(x,y)

     register()

    3、空函数

     def func():

         pass

    def check_user():

        pass

    def check_pwd():

        pass

    def write_db(x,y):

        pass

    def register():

        #1 输入用户名,并进行合法性校验

        #2 输入密码,并进行合法性校验

        #3 将合法的用户名、密码写入文件

        x=check_user()

        y=check_pwd()

        write_db(x,y)

    '函数的返回值

    1、什么是返回值

        返回值是一个函数的处理结果,

    2、为什么要有返回值

        如果我们需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须有返回值

    3、函数的返回值的应用

        函数的返回值用return去定义

        格式为:

            return 值

        注意:

            1、return是一个函数结束的标志,函数内可以有多个return,

                但只要执行一次,整个函数就会结束运行

            2、return 的返回值无类型限制,即可以是任意数据类型

            3、return 的返回值无个数限制,即可以用逗号分隔开多个任意类型的值

                0个:返回None,ps:不写return默认会在函数的最后一行添加return None

                1个:返回的值就是该值本身

                多个:返回值是元组

    '''

    # def max2(x,y): #x=3000,y=2000

    #     if x > y:

    #         return x #return 3000

    #     else:

    #         return y #reuturn 2000

    #

    # res=max2(3000,2000)

    #

    # annual_salary=res * 12

    #

    # print(annual_salary)

    # def foo():

    #     print(1)

    #     print(2)

    #     print(3)

    #     return [1,2,3],'a',('a','b'),{1,2}

    #     print(4)

    #     print(5)

    #     print(6)

    #

    # res=foo()

    # print(res)

    # def bar():

    #     print(1)

    #     print(1)

    #     print(1)

    #     print(1)

    #     return

    #     print(2)

    #     print(3)

    #     print(4)

    #

    # res=bar()

    # print(res)

    函数的调用

    1 什么是调用函数

        函数名(...)即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

    2 为何要调用函数

        用函数的功能

    3、函数调用分为三种形式

        max2(1,2)

        res=max2(3000,2000) * 12

        res=max2(max2(1000,2000),3000)

    '''

    # def foo():

    #     print(1)

    #     print(2)

    #     print(3)

    #     return None

    # res=foo()

    # print(res)

    def max2(x,y):

        if x > y:

            return x

        else:

            return y

    #形式一:

    # max2(1,2)

    #形式二:

    # res=max2(3000,2000) * 12

    # print(res)

    #形式三:

    res=max2(max2(1000,2000),3000)

    print(res)

    函数的参数

    #总的分类:

    # #1、形参:在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,本质就是变量名

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

    #     print(x)

    #     print(y)

    # #2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参,本质就是变量的值

    # foo(1,2)

    #

    #详细的分类:

    #一、位置参数:

    #位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参

    #特点:但凡是按照位置定义的形参,都必须被传值,多一个不行,少一个也不行

    # def foo(x,y):

    #     print('x:',x)

    #     print('y:',y)

    #位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参

    #特点:按照位置为对应的形参依次传值

    # foo(1,2)

    # foo(2,1)

    #二、关键字实参:在调用函数时,按照key=value的形式为指定的参数传值,称为关键字实参

    #特点:可以打破位置的限制,但仍能为指定的形参赋值

    # foo(y=2,x=1)

    #注意:

    #1、可以混用位置实参与关键字实参,但位置实参必须放在关键字实参的前面

    # foo(1,y=2)

    # foo(y=2,1) #SyntaxError: positional argument follows keyword argument

    #2、可以混用,但不能对一个形参重复赋值

    # foo(1,y=2,x=10)

    #三:默认参数:在函数定义阶段,就已经为形参赋值,该形参称为默认形参

    #特点:在定义阶段就已经被赋值,意味着在调用可以不用为其赋值

    # def foo(x,y=10):

    #     print('x:',x)

    #     print('y:',y)

    # foo(1)

    # foo(1,3)

    # 注意:

    #1、位置形参必须放到默认形参的前面,否则报语法错误

    # def foo(x=1,y):

    #     pass

    #2、默认参数的值只在定义阶段赋值一次,即默认参数的值在函数定义阶段就已经固定死了

    # m=10

    # def foo(x=m,y=11):

    #     print(x)

    #     print(y)

    # m=1111111111111111111111111111111111111111111111111111111111

    # foo()

    #3、默认参数的值通常应该定义不可变类型

    # def register(name,hobby,hobbies=[]):

    #     hobbies.append(hobby)

    #     print('%s的爱好' %name,end=':')

    #     print(hobbies)

    #

    # register('egon','play')

    # register('alex','piao')

    # register('lxx','烫头')

    # def register(name,hobby,hobbies=None):

    #     if hobbies is None:

    #         hobbies=[]

    #     hobbies.append(hobby)

    #     print('%s的爱好' %name,end=':')

    #     print(hobbies)

    #

    # register('egon','play')

    # register('alex','piao')

    # register('lxx','烫头')

    #总结:

    #实参的应用:取决于个人习惯,

    #形参的应用:

    #1、位置形参:大多数情况下的调用值都不一样,就应该将该参数定义成位置形参

    #2、默认形参:大多数情况下的调用值都一样,就应该将该参数定义成默认形参

    # def register(name,age,sex='male'):

    #     print(name)

    #     print(age)

    #     print(sex)

    #

    #

    # register('egon',18,)

    # register('大脑门',73,'female')

    # register('小脑门',84,)

    # register('大高个',18,)

    #四:可变长参数:指的是在调用函数时,传入的参数个数可以不固定

    #而调用函数时,传值的方式无非两种,一种位置实参,另一种时关键字实参

    #所以对应着,形参也必须有两种解决方案,来分别接收溢出的位置实参(*)与关键字实参(**)

    #1、形参中某个参数带*

    #形参中的*会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的变量名

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

    #     print(x)

    #     print(y)

    #     print(z)

    # foo(1,2,3,4,5,6,7)

    # 应用

    # def my_sum(*nums):

    #     res=0

    #     for num in nums:

    #         res+=num

    #     return res

    #

    # print(my_sum(1,2,3,4,5))

    # 2、实参中的参数也可以带*

    # 实参中带*,*会将该参数的值循环取出,打散成位置实参

    #ps:以后但凡碰到实参中带*的,它就是位置实参,应该立马打散成位置实参去看

    # def foo(x,y,z):

    #     print(x,y,z)

    # foo(1,*[2,3]) #foo(1,2,3)

    # foo(1,*'he') #foo(1,'h','e')

    # foo(1,*(2,3,4)) #foo(1,2,3,4)

    # def foo(x,y,z,*args):

    #     print(x)

    #     print(y)

    #     print(z)

    #     print(args)

    #

    # foo(1,2,3,4,5,6,7,*[8,9,10,11]) #foo(1,2,3,4,5,6,7,8,9,10,11)

    #注意:约定俗成形参中的*变量名的写法都是:*args

    #1、形参中某个参数带**

    #形参中的**会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给**后的变量名

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

    #     print(x)

    #     print(y)

    #     print(z)

    # foo(1,2,a=3,b=4,c=5)

    # 2、实参中的参数也可以带**,该参数必须是字典

    # 实参中带**,**会将该参数的值循环取出,打散成关键字实参

    #ps:以后但凡碰到实参中带**的,它就是关键字实参,应该立马打散成关键字实参去看

    # def foo(x,y,z):

    #     print(x)

    #     print(y)

    #     print(z)

    # foo(1,2,**{'a':1,'b':2,'c':3,'z':3}) #foo(1,2,c=3,b=2,a=1,z=3)

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

    #注意:约定俗成形参中的**变量名的写法都是:**kwargs

    # def index(name,age,sex):

    #     print('welecome %s:%s:%s to index page' %(name,age,sex))

    #

    # def wrapper(*args,**kwargs): #args=(1,),kwargs={'x': 1, 'y': 2, 'z': 3}

    #     index(*args,**kwargs) #index(*(1,),**{'x': 1, 'y': 2, 'z': 3}) #index(1,x=1,y=2,z=3)

    #

    # wrapper(name='egon',sex='male',age=18)

    #

    #五 命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数(**)

    # 特点:在传值时,必须按照key=value的传,并且key必须命名关键字参数指定的参数名

    # def register(x,y,z,**kwargs): #kwargs={'b':18,'a':'egon'}

    #     if 'name' not in kwargs or 'age' not in  kwargs:

    #         print('用户名与年龄必须使用关键字的形式传值')

    #         return

    #     print(kwargs['name'])

    #     print(kwargs['age'])

    # register(1,2,3,a='egon',b=18)

    # def register(x,y,z,*args,name='egon',age):

    #     print(args)

    #     print(name)

    #     print(age)

    # register(1,2,3,4,5,6,7,age=18)

    #

    # def foo(x,y=1,*args,z=1,a,b,**kwargs):

    #     pass

    # foo(1,*[1,2,3],a=1,**{'x':1,'y':2}) #foo(1,1,2,3,a=1,y=2,x=1)

    # foo(1,2)

    # foo(x=1,y=2)

    open('a.txt','w',encoding='utf-8')

    函数的对象

    #函数是第一类对象的含义是函数可以被当作数据处理

    def func(): #func=<function func at 0x0584BA50>

        print('from func')

    # print(func)

    x='hello'

    #1、引用

    # y=x

    # f=func

    # print(f)

    # f()

    #2、当作参数传给一个函数

    # len(x)

    # def foo(m):

    #     # print(m)

    #     m()

    #

    # foo(func)

    #3、可以当作函数的返回值

    # def foo(x): #x=func

    #     return x #return func

    #

    # res=foo(func)

    # print(res)

    # res()

    #4、可以当作容器类型的元素

    # l=[x,]

    # l=[func,]

    # # print(l)

    #

    # l[0]()

    def pay():

        print('支付。。。')

    def withdraw():

        print('取款。。。')

    def transfer():

        print('转账。。。')

    def check_balance():

        print('查看余额。。。')

    def shopping():

        print('购物。。。')

    func_dic={

        '1':pay,

        '2':withdraw,

        '3':transfer,

        '4':check_balance,

        '6':shopping

    }

    while True:

        msg="""

        1 支付

        2 取款

        3 转账

        4 查看余额

        5 退出

        6 购物

        """

        print(msg)

        choice=input('>>: ').strip()

        if choice == '5':break

        if choice not in func_dic:

            print('输入的指令不存在傻叉')

            continue

        func_dic[choice]()

     函数嵌套

    #函数的嵌套定义

    def f1():

        def f2():

            print('from f2')

        f2()

    f1()

    # from math import pi

    #

    # def circle(radius,action='area'): #radius=10

    #     def area():

    #         return pi * (radius ** 2)

    #

    #     def perimeter():

    #         return 2 * pi * radius

    #

    #     if action == 'area':

    #         return area()

    #     elif action == 'perimeter':

    #         return perimeter()

    #

    # print(circle(10))

    # print(circle(10,action='perimeter'))

    #函数的嵌套调用

    # 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))

     名称空间和作用域

    1、名称空间namespaces

        存放名字与值绑定关系的地方

    2、名称空间分为三大类

        内置名称空间:

            作用:存放python解释器自带的名字

            生命周期:

                在解释器启动时生效,在解释器关闭时失效

        全局名称空间:

            作用:除了内置的与局部的名字外,其余都是全局名字

            生命周期:

                在文件执行时生效,在文件执行完毕时失效

            例如:x,func,y,l,z都是

                x=1

                def func():

                    a=1

                y=2

                l=[1,2]

                if 3 > 2:

                    if

                        if

                            if

                                z=3

        局部名称空间:

            作用:用于存放函数调用期间函数体产生的名字

            生命周期:

                在文件执行过程

                如果调用了某个函数才会临时生效,在函数执行完毕后失效

        三种名称空间的加载顺序是:

            内置-》全局-》局部

        名称空间就是用来存放名字与值的绑定关系的,所以但凡要查找名字

        一定是从三者之一找到,查找顺序:

            从当前所在的位置倒着查找,如果当前所在的位置是局部名称空间,

            则查找顺序是:

                局部-》全局-》内置

    3、作用域:

        域指的是区域、范围,作用域即作用的范围

        全局作用范围,全局作用域(内置名称空间与全局名称空间)

            全局有效,全局存活

        局部作用范围,局部作用域(局部名称空间)

            局部有效,临时存活

    '''

    # x=1

    # # len=100

    # def func():

    #     y=2

    #     len=1000

    #     # print(len)

    #     print(a)

    # # func()

    #

    # print(len)

    # def func():

    #     y=2

    #     print(x)

    #

    # x=1

    # func()

    #

    # x=10

    # x=1

    # def f1():

    #     def f2():

    #         def f3():

    #             zzz=333

    #             print(x)

    #         # x = 22222

    #         f3()

    #     # x=111111

    #     f2()

    #

    # def bar():

    #     print(x)

    #

    # f1()

    # bar()

    # 作用域关系是在函数定义阶段就固定死了,但凡调用函数都需要跑到定义阶段去找作用域关系

    # x=1

    # def f1():

    #     print(x)

    #

    # # f1()

    # x=1000000000000000000000000000000000000000000000000000000000000000

    # def f2():

    #     # print(f1)

    #     x=11111111111111111111111111111

    #     f1()

    #

    # f2()

    #函数对象+作用域:******

    # def f1():

    #     x=1

    #     def inner():

    #         print('from inner',x)

    #     return inner

    #

    # f=f1()

    #

    # # print(f)

    #

    # def bar():

    #     x=111111111111111111111111111111111111111111111

    #     f()

    #

    # bar()

    #

    # x=1

    # def foo():

    #     global x

    #     x=2

    #

    # foo()

    # print(x)

    # x=1

    # def f1():

    #     def f2():

    #         x=22222222

    #         def f3():

    #             global x

    #             x=11111111111111111

    #         f3()

    #     f2()

    #

    # f1()

    # print(x)

    # x=1

    # def f1():

    #     # x=33333

    #     def f2():

    #         # x=22222222

    #         def f3():

    #             nonlocal x

    #             x=20000000000

    #         f3()

    #         print(x)

    #     f2()

    #

    # f1()

    # print(x)

    # 在局部如果想要修改全局的可变类型,不需要借助任何声明,可以直接修改

    # 在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以直接修改了

    # x=[]

    # def f1():

    #     x.append(1)

    # f1()

    # f1()

    # print(x)

     闭包函数

    #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关

    # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系

    # def f1():

    #     x=1

    #     def inner():

    #         print(x)

    #

    #     return inner

    #

    # func=f1()

    #

    # def f2():

    #     x=111111

    #     func()

    #

    # f2()

    # 闭包函数:

    # 闭指的是:该函数是一个内部函数

    # 包指的是:指的是该函数包含对外部作用域(非全局作用域)名字的引用

    # def outter():

    #     x = 1

    #     def inner():

    #         print(x)

    #

    #     return inner

    #

    # f=outter()

    #

    # def f2():

    #     x=1111111

    #     f()

    #

    # f2()

    #

    #

    # def f3():

    #     x=4444444444444

    #     f()

    #

    # f3()

    # 为函数体传值的方式一:使用参数的形式

    # def inner(x):

    #     print(x)

    #

    # inner(1)

    # inner(1)

    # inner(1)

    # 为函数体传值的方式二:包给函数

    '''

    def outter(x):

        # x=1

        def inner():

            print(x)

        return inner

    f=outter(1)

    f()

    '''

    # import requests

    #

    # def get(url):

    #     response=requests.get(url)

    #     if response.status_code == 200:

    #         print(response.text)

    #

    # get('https://www.baidu.com')

    # get('https://www.baidu.com')

    # get('https://www.baidu.com')

    #

    # get('https://www.python.org')

    # get('https://www.python.org')

    # get('https://www.python.org')

    # get('https://www.python.org')

    import requests

    def outter(url):

        # url='https://www.baidu.com'

        def get():

            response=requests.get(url)

            if response.status_code == 200:

                print(response.text)

        return get

    baidu=outter('https://www.baidu.com')

    python=outter('https://www.python.org')

    baidu()

    baidu()

    python()

    python()

    装饰器

    '''

    1、什么是装饰器

        器指的是工具,而程序中的函数就具备某一功能的工具

        装饰指的是为被装饰器对象添加额外功能

        就目前的知识来看:

            定义装饰器就是定义一个函数,只不过该函数的功能是用来为

            其他函数添加额外的功能

        其实:

            装饰器本身其实可以是任意可调用的对象

            被装饰的对象也可以是任意可调用的对象

    2、为什么要用装饰器

        软件的维护应该遵循开放封闭原则

        开放封闭原则指的是:

            软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的

            这就用到了装饰器

        装饰器的实现必须遵循两大原则:

            1、不修改被装饰对象的源代码

            2、不修改被装饰对象的调用方式

        装饰器其实就在遵循1和2原则的前提下为被装饰对象添加新功能

    3、如何用装饰器

    '''

    # import time

    #

    # def index():

    #     start=time.time()

    #     print('welcom to index')

    #     time.sleep(3)

    #     stop=time.time()

    #     print('run time is %s' %(stop-start))

    # index()

    # import time

    #

    # def index():

    #     print('welcom to index')

    #     time.sleep(3)

    #

    # def f2():

    #     print('from f2')

    #     time.sleep(2)

    #

    # start=time.time()

    # index()

    # stop=time.time()

    # print('run time is %s' %(stop-start))

    #

    # start=time.time()

    # f2()

    # stop=time.time()

    # print('run time is %s' %(stop-start))

    # import time

    #

    # def index():

    #     print('welcom to index')

    #     time.sleep(3)

    #

    # def timmer(func):

    #     start=time.time()

    #     func()

    #     stop=time.time()

    #     print('run time is %s' %(stop-start))

    #

    # timmer(index)

    '''

    import time

    def index():

        print('welcom to index')

        time.sleep(3)

    def timmer(func): #func=最原始的index

        # func=index

        def inner():

            start=time.time()

            func()

            stop=time.time()

            print('run time is %s' %(stop-start))

        return inner

    # f=timmer(index)

    # f()

    # index=timmer(被装饰函数的内存地址)

    index=timmer(index) #index=inner

    index() #inner()

    '''

    import time

    def index():

        print('welcom to index')

        time.sleep(3)

    def timmer(func):

        #func=最原始的index

        def wrapper():

            start=time.time()

            func()

            stop=time.time()

            print('run time is %s' %(stop - start))

        return wrapper

    index=timmer(index) #index=wrapper函数的内存地址

    index()

     装饰器修正

    无参装饰器

     # import time

    #

    # def index():

    #     print('welcome to index')

    #     time.sleep(3)

    #     return 123

    #

    # def home(name):

    #     print('welcome %s to home page' %name)

    #     time.sleep(2)

    #

    #

    # def timmer(func):

    #     #func=最原始的index

    #     def wrapper(*args,**kwargs):

    #         start=time.time()

    #         res=func(*args,**kwargs)

    #         stop=time.time()

    #         print('run time is %s' %(stop - start))

    #         return res

    #     return wrapper

    #

    #

    # index=timmer(index)

    # home=timmer(home)

    #

    # res=index()

    # home('egon')

    #装饰器语法糖

    # 在被装饰对象正上方,并且是单独一行写上@装饰器名

    # import time

    # def timmer(func):

    #     #func=最原始的index

    #     def wrapper(*args,**kwargs):

    #         start=time.time()

    #         res=func(*args,**kwargs)

    #         stop=time.time()

    #         print('run time is %s' %(stop - start))

    #         return res

    #     return wrapper

    #

    # @timmer # index=timmer(index)

    # def index():

    #     print('welcome to index')

    #     time.sleep(3)

    #     return 123

    #

    # @timmer # home=timmer(home)

    # def home(name):

    #     print('welcome %s to home page' %name)

    #     time.sleep(2)

    #

    # res=index()

    # home('egon')

    def deco(func):

        def wrapper(*args,**kwargs):

            res=func(*args,**kwargs)

            return res

        return wrapper

    有参装饰器

    import time

    current_user={'user':None}

    def deco(func):

        def wrapper(*args,**kwargs):

            if current_user['user']:

                #已经登陆过

                res = func(*args, **kwargs)

                return res

            user=input('username>>: ').strip()

            pwd=input('password>>: ').strip()

            if user == 'egon' and pwd == '123':

                print('login successful')

                # 记录用户登陆状态

                current_user['user']=user

                res=func(*args,**kwargs)

                return res

            else:

                print('user or password error')

        return wrapper

    @deco

    def index():

        print('welcome to index page')

        time.sleep(1)

    @deco

    def home(name):

        print('welecome %s to home page' %name)

        time.sleep(0.5)

    index()

    home('egon')

    '''

    '''

    def f1():

        x=1

        def f2():

            def f3():

                print(x)

            return f3

        return f2

    f2=f1()

    f3=f2()

    f3()

    '''

    import time

    current_user={'user':None}

    def auth(engine='file'):

        def deco(func):

            def wrapper(*args,**kwargs):

                if current_user['user']:

                    #已经登陆过

                    res = func(*args, **kwargs)

                    return res

                user=input('username>>: ').strip()

                pwd=input('password>>: ').strip()

                if engine == 'file':

                    # 基于文件的认证

                    if user == 'egon' and pwd == '123':

                        print('login successful')

                        # 记录用户登陆状态

                        current_user['user']=user

                        res=func(*args,**kwargs)

                        return res

                    else:

                        print('user or password error')

                elif engine == 'mysql':

                    print('基于mysql的认证')

                elif engine == 'ldap':

                    print('基于ldap的认证')

                else:

                    print('无法识别认证来源')

            return wrapper

        return deco

    @auth(engine='mysql') # @deco #index=deco(index) #index=wrapper

    def index():

        print('welcome to index page')

        time.sleep(1)

    @auth(engine='mysql')

    def home(name):

        print('welecome %s to home page' %name)

        time.sleep(0.5)

    index()

    home('egon')

    迭代器

    '''

    1、什么是迭代器

        迭代器即迭代取值的工具

        迭代:

            迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的

            单纯的重复并不是迭代

            while True:

                print('1111')

            迭代:

            l=['a','b','c']

            def iterator(item):

                i=0

                while i < len(item):

                    print(l[i])

                    i+=1

    2、 为什么要有迭代器

        基于索引的迭代器取值方式只适用于列表、元组、字符串类型

        而对于没有索引的字典、集合、文件,则不在适用

        所以必须找到一种通用的并且不依赖于索引的迭代器取值方式=》迭代器

        迭代器适用于可迭代的类型

    3、如何用迭代器

    '''

    # l=['a','b','c']

    # i=0

    # while i < len(l):

    #     print(l[i])

    #     i+=1

    # l = ['a', 'b', 'c']

    # s='hello'

    #

    # def iterator(item): #item='hello'

    #     i = 0

    #     while i < len(item):

    #         print(item[i])

    #         i += 1

    # # iterator(l)

    # iterator(s)

    # 可迭代的对象:在python中但凡内置有__iter__方法的对象都是可迭代的对象

    # 字符串、列表、元组、字典、集合、文件都是可迭代的对象

    # num1=10

    # num2=10.1

    # s1='hello'

    # l=[1,2,3]

    # t=(1,2,3)

    # d={'x':1}

    # s2={1,2,3}

    # f=open('a.txt','w')

    #

    # s1.__iter__

    # l.__iter__

    # t.__iter__

    # d.__iter__

    # s2.__iter__

    # f.__iter__

    #

    #

    # 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象

    #执行可迭代对象的__iter__方法得到的就是内置的迭代器对象

    # 文件对象本身就是迭代器对象

    #强调:

    #1、迭代器对象一定是可迭代的对象,反之则不然

    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

    # info_iter=info.__iter__()

    # # print(info_iter)

    #

    # res1=info_iter.__next__()

    # print(res1)

    #

    # res2=info_iter.__next__()

    # print(res2)

    #

    # res3=info_iter.__next__()

    # print(res3)

    #

    # res4=info_iter.__next__()

    # print(res4)

    #

    # info_iter.__next__() # 一旦迭代器取值取干净,再继续取就会抛出StopIteration

    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

    # # info=[1,2,3,4,5]

    # info_iter=info.__iter__()

    # while True:

    #     try:

    #         print(info_iter.__next__())

    #     except StopIteration:

    #         break

    #for循环:迭代器循环

    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

    #in后跟的一定要是可迭代的对象

    # for k in info: # info_iter=info.__iter__()

    #     print(k)

    # f=open('a.txt','r')

    # for k in f:

    #     print(k)

    # 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象

    # 执行迭代器对象的__next__得到的是迭代器的下一个值

    # 执行迭代器对象的__iter__得到的仍然是迭代器本身

    # iter_info=info.__iter__()

    # # print(iter_info)

    # print(iter_info is iter_info.__iter__() is iter_info.__iter__().__iter__().__iter__().__iter__().__iter__())

    #

    #总结迭代器对象的优缺点:

    #优点:

    1、提供了一种通用的、可以不依赖索引的迭代取值方式

    2、迭代器对象更加节省内存

    # 缺点:

    #1、迭代器的取值不如按照索引的方式更灵活,因为它只能往后取不能往前退

    #2、无法预测迭代器值的个数

    # names=['egon','alex_SB','wxx_SB']

    # iter_names=iter(names)

    # print(next(iter_names))

    生成器

    '''

    1 什么是生成器?

    在函数内但凡出现yield关键字,再调用函数就不会执行函数体代码,会返回值一个值,该值称之为生成器

     生成器本质就是迭代器

    2、为什么要有生成器?

        生成器是一种自定义迭代器的方式

    3、如何用生成器

    '''

    # def func():

    #     print('first1')

    #     print('first2')

    #     print('first3')

    #     yield 1 #暂停

    #     print('second1')

    #     print('second2')

    #     print('second3')

    #     yield 2  #暂停

    #     print('third')

    #     yield 3 #暂停

    #     print('fourth')

    #

    # g=func()

    # print(g)

    # print(g.__iter__().__iter__().__iter__() is g)

    # res1=next(g)

    # print('第一次的返回值:',res1)

    #

    # print('='*100)

    # res2=next(g)

    # print('第二次的返回值:',res2)

    #

    # print('='*100)

    # res3=next(g)

    # print('第三次的返回值:',res3)

    #

    # print('='*100)

    # res4=next(g)

    # print('第三次的返回值:',res4)

    # for item in g: #g=iter(g) #item=next(g)

    #     print(item)

    # i=range(1,1000)

    # for item in range(1,1000000000)

    # def my_range(start,stop,step=1):

    #     while start < stop:

    #         yield start # 暂停

    #         start+=step

    # g=my_range(1,5,2) #1 3

    # print(next(g))

    # print(next(g))

    # print(next(g))

    # print(next(g))

    # print(next(g))

    # print(next(g))

    # print(next(g))

    # for item in g:

    #     print(item)

    #总结yield的功能

    #1、提供一种自定义迭代器的方式

    #2、yield可以暂停住函数,返回值

    #yield  VS return

    #相同点:都是用在函数内,都可以返回值,没有类型限制,没有个数限制

    #不同点:return只能返回一次值,yield可以返回多次值

    # 了解知识

    # yield 值

    # x=yield

    # x= yield 值

    def dog(name):

        food_list=[]

        print('狗哥 %s 准备开吃' %name)

        while True:

            food=yield food_list#暂停 food=yield='一桶泔水'

            print('狗哥[%s]吃了<%s>' %(name,food))

            food_list.append(food)

    alex_dog=dog('alex')

    res1=next(alex_dog) # 初始化,即让狗准备好

    print(res1)

    # next(alex_dog) # 等同于alex_dog.send(None)

    #

    # next(alex_dog)

    res2=alex_dog.send(('一泡翔','咖啡伴侣'))

    print(res2)

    res3=alex_dog.send('一桶泔水')

    print(res3)

    #

    # 列表生成式

    # l=[item**2 for item in range(1,11)]

    # print(l)

    # names=['alex','wxx','lxx']

    # l=[]

    # for name in names:

    #     l.append(name + 'SB')

    # names=l

    # names=[name+'SB' for name in names]

    # print(names)

    # names=['alex','wxx','egon','lxx','zhangmingyan']

    # l=[]

    # for name in names:

    #     if name != 'egon':

    #         l.append(name + 'SB')

    # names=l

    # names=[name+'SB' for name in names if name != 'egon']

    # print(names)

    # l=[item**2 for item in range(1,5) if item > 2]

    # print(l)

    # names=['egon','alex_sb','wupeiqi','yuanhao']

    # names=[name.upper() for name in names]

    # print(names)

    # names=['egon','alex_sb','wupeiqi','yuanhao']

    #

    # nums=[len(name) for name in names if not name.endswith('sb')]

    # print(nums)

    #字典生成式

    # s1='hello'

    # l1=[1,2,3,4,5]

    # res=zip(s1,l1)

    # print(res)

    # print(list(res))

    # keys=['name','age','sex']

    # values=['egon',18,'male']

    # res=zip(keys,values)

    # print(list(res))

    # print(list(res))

    # d={}

    # for k,v in zip(keys,values):

    #     d[k]=v

    # print(d)

    # keys=['name','age','sex']

    # values=['egon',18,'male']

    # d={k:v for k,v in zip(keys,values)}

    # print(d)

    info={'name': 'egon', 'age': 18, 'sex': 'male'}

    keys=info.keys()

    # print(keys)

    # iter_keys=keys.__iter__()

    # values=info.values()

    # print(values)

     函数递归

    1 什么是函数递归

        函数递归调用(是一种特殊的嵌套调用):在调用一个函数的过程中,又直接或间接地调用了该函数本身

        递归必须要有两个明确的阶段:

            递推:一层一层递归调用下去,强调每进入下一层递归问题的规模都必须有所减少

            回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推

                开始一层一层回溯

        递归的精髓在于通过不断地重复逼近一个最终的结果

    2、为什么要用函数递归

    3、如何用

    '''

    # import sys

    # print(sys.getrecursionlimit())

    # sys.setrecursionlimit(3000)

    # def foo(n):

    #     print('from foo',n)

    #     foo(n+1)

    # foo(0)

    # def bar():

    #     print('from bar')

    #     foo()

    #

    # def foo():

    #     print('from foo')

    #     bar()

    # foo()

    # age(5) = age(4) + 2

    # age(4) = age(3) + 2

    # age(3) = age(2) + 2

    # age(2) = age(1) + 2

    # age(1) = 26

    # age(n) = age(n-1) + 2 #n > 1

    # age(1) = 26           #n = 1

    # def age(n):

    #     if n == 1:

    #         return 26

    #     return age(n-1) + 2

    #

    # print(age(5))

    # l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

    #

    # def tell(l):

    #     for item in l:

    #         if type(item) is list:

    #             #继续进入下一层递归

    #             tell(item)

    #         else:

    #             print(item)

    #

    # tell(l)

    # 有一个从小到大排列的整型数字列表

    # nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]

    # 10 in nums

    # for item in nums:

    #     if item == 10:

    #         print('find it')

    #         break

    # else:

    #     print('not exists')

    nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]

    def search(search_num,nums):

        print(nums)

        if len(nums) == 0:

            print('not exists')

            return

        mid_index=len(nums) // 2

        if search_num > nums[mid_index]:

            # in the right

            nums=nums[mid_index+1:]

            search(search_num,nums)

        elif search_num < nums[mid_index]:

            # in the left

            nums=nums[:mid_index]

            search(search_num,nums)

        else:

            print('find it')

    匿名函数

    # 有名函数:基于函数名重复使用

    # def func():

    #     print('from func')

    # func()

    # func()

    # func()

    # 匿名函数:没有绑定名字的下场是用一次就回收了

    # def func(x,y): #func=函数的内存地址

    #     return x + y

    # res=(lambda x,y:x+y)(1,2)

    # print(res)

    # f=lambda x,y:x+y

    # print(f)

    # print(f(1,2))

    #max min map filter sorted

    salaries={

        'egon':3000,

        'alex':100000000,

        'wupeiqi':10000,

        'yuanhao':2000

    }

    # max的工作原理

    #1 首先将可迭代对象变成迭代器对象

    #2 res=next(可迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据

    # def func(k):

    #     return salaries[k]

    #

    # print(max(salaries,key=func)) #next(iter_s)

    #'egon', v1=func('egon')

    #'alex', v2=func('alex')

    #'wupeiqi', v3=func('wupeiqi')

    #'yuanhao', v4=func('yuanhao')

    # salaries={

    #     'egon':3000,

    #     'alex':100000000,

    #     'wupeiqi':10000,

    #     'yuanhao':2000

    # }

    # print(max(salaries,key=lambda k:salaries[k])) #next(iter_s)

    # print(min(salaries,key=lambda k:salaries[k])) #next(iter_s)

    # l=[10,1,3,-9,22]

    # l1=sorted(l,reverse=False)

    # print(l1)

    # l2=sorted(l,reverse=True)

    # print(l2)

    # salaries={

    #     'egon':3000,

    #     'alex':100000000,

    #     'wupeiqi':10000,

    #     'yuanhao':2000

    # }

    #

    # print(sorted(salaries,key=lambda k:salaries[k],reverse=True))

    names=['张明言','刘华强','苍井空','alex']

    # map的工作原理

    #1 首先将可迭代对象变成迭代器对象

    #2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一

    # aaa=map(lambda x:x+"_SB",names)

    # print(aaa)

    # print(list(aaa))

    # print([name+"_SB" for name in names])

    # filter的工作原理

    #1 首先将可迭代对象变成迭代器对象

    #2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下res

    names=['alexSB','egon','wxxSB','OLDBOYSB']

    # print([name for name in names if name.endswith('SB')])

    aaa=filter(lambda x:x.endswith('SB'),names)

    print(aaa)

    print(list(aaa))

    内置方法

    abs() 求一个数字的最大值

    bytes() 将一个字符串转换成一个bytes类型

    bool()给出一个数据的布尔值

    min()求出最小的值参数必须是可迭代对象  其中可跟lambda匿名函数的参数

    max()求出最大的值参数必须是可迭代对象  其中可跟lambda匿名函数的参数

    sum()求出总和参数必须是可迭代对象 其中可跟lambda匿名函数的参数

    zip()将两个可迭代的数据每一次next取出一个数据将两者拼接成一个个的小元组

    chr()将一个Ascll码转换成为一个对应的字符

    ord()chr的反向操作

    otc()讲一个十进制数字转换成八进制数字

    bin()将一个十进制数字转换成二进制数字

    hex() 讲一个十进制数字转换成十六进制数字

    int()将一个字符串转换成一个十进制数字  或者将一个二进制八进制十六进制字符串  转换成十进制数字可以,通过int(‘101010101’,2)其中2代表字符串代表的是一个二进制字符数字,

    list()讲一个可迭代对象里面的值一个个取出生成一个列表

    __import__()与import不同的是该方法可以将字符串代表的模块名导入程序例如 x = __import('time')

    eval()可以将一个字符串中的列表字典等数据提取出来

    open()用于建立一个文件的读取管道

    dir()获取模块中的方法名

    help()获取函数中的注释

    type()查看数据类型

  • 相关阅读:
    0102-进程操作(面向对象简单工厂模式,打开输入文件)
    0101-进程操作(变量命名)
    win10无法成功完成操作因为文件包含病毒或潜在的垃圾软件如何处理
    序列化和反序列化
    __slot__的用法
    python中typeguard包
    pandas如何将多个DataFrame写入同一个excel工作簿中
    DEAP库遗传算法
    【教程】如何把喜马拉雅音频下载到电脑
    oracle安装路径查看方式
  • 原文地址:https://www.cnblogs.com/wanglecn/p/9142397.html
Copyright © 2011-2022 走看看