zoukankan      html  css  js  c++  java
  • python 函数基础及装饰器

    没有参数的函数及return操作

    def test1():
        print ("welcome")
    
    def test2():
        print ("welcomt test2")
        return 0
    
    def test3():
        print("welcome test3")
        return 0,324,123,["test3","retest"]
    
    
    x = test1()            #test1()表示执行,将执行结果(返回值)赋给变量x,会自动执行,并且由于test1 没有返回值(没有return操作),print的时候会打印none
    y = test2()            #test2()执行,有print,也有return,由于return一个返回值,所以将return的值赋给变量y
    z = test3()
    
    print (x)
    print (test1)          ----test1没有执行,会打印test1的内存对象 print (y)             print (z) 打印结果: welcome          ----》x的打印结果 welcomt test2       ----》 y的打印结果 welcome test3       ----》 z的打印结果 None            ----》x的打印结果
    0              -----》y的打印结果 (0, 324, 123, ['test3', 'retest'])   ---》z的打印结果 总结: 只有当函数赋给一个变量时,返回值才能打印出来    当返回值为0时(没有return操作):返回none 当返回值为1时(return n):返回n 当返回值大于1时(return a,b,bv,d):返回元组(a,b,bv,d)

    带参数的函数

    #位置参数调用
    def test1(x,y):       ##这里的x,y称之为形参
        print (x)
        print (y)
        
    test1(1,2)             ###这里的1,2称之为实参
    
    注:形参和实参位置必须一一对应,##关键参数不能写在位置参数前面
    
    ##关键字调用,与形参顺序无关
    def test1(x,y):      
        print (x)
        print (y)
    
    test1(y=1,x=2)    
    
    这里 y=1 将值传给y,x=2将值传给x

    参数组(非固定参数)

    #打印出一个元组(n个参数转换成元组)
    def test1(*args):             ##传多个位置参数(及单个字符串类的参数),在参数不固定的情况下
        print (args)
    
    test1(1,2,3,4,5)
    
    
    ##打印一个字典(n个参数转换成字典)
    def test1(**kwargs):              ###接收多个关键字参数(及 键=值 类似的参数)
        print (kwargs)
    
    test1(name='aa',age=99,sex="man")
    
    
    注:参数组一定要放在后面

    高阶函数和嵌套函数

    高阶函数说明:

    • A:函数名当作实参传递给另一个函数
    • B:函数名可以作为返回值

    示例一:将函数名作为实参,传递给另一个函数

    打印结果:

    示例二:将函数名作为返回值

    def bar():
        print ('in the bar')
       return "xx" 
    def test1(func): print (func) return func        #func为传递进来的函数名,作为返回值返回,return的结果一个内存对象 print (test1(bar)) ##打印bar的内存地址(test1(bar)即将bar的内存作为参数地址传给 test1即func=bar,print (func)则打印的bar的内存地址,return也返回bar的内存地址) x=test1(bar)         #这里bar不能加括号’()’,加了括号相当于把bar的返回值(相当于执行了bar,返回值为xx)传过去了,而不是传了一个函数
    print (x())          #相当于执行了bar函数

    执行结果:

    <function bar at 0x0000020090A57F28>         #print(func) 的值
    <function bar at 0x0000020090A57F28>         #return func的值
    <function bar at 0x0000020090A57F28>         X = test1(bar)的值
    in the bar                        #x()的值
    xx

    示例:

     retrun func 返回func的内存地址,t()相当于执行func,返回func函数的执行结果

    嵌套函数

    def foo():
        print ('in the foo')
        def bar():
            print ('in the bar')
        bar()
    
    foo()
    
    打印结果:
    
    in the foo
    in the bar

    装饰器

    一、无参数装饰器

    import time
    
    def timer(func):
        def deco():
            start_time = time.time()
            func()                        #func()=test1()
            stop_time = time.time()
            print ("the func run time is %s" % (stop_time-start_time))
        return deco             ##返回deco的内存地址
    
    @timer                ### 等价于 test1=timer(test1),将test1函数的作为实参传给timer,所以test1=func,func()=test1()
    def test1():
        time.sleep(3)
        print ("in the test1")
    
    
    print (timer(test1))      ##打印deco的内存地址#此时会打印deco的内存地址(因为,将test1函数传给timer,即func=test1,此时无论deco函数做啥操作,deco函数都没有执行,最后直接执行的是return deco,返回deco的内存地址)
    
    r = timer(test1)          ##将deco的返回值(内存地址)赋给r,r() 则会执行deco这个函数(即deco())
    r()

    打印结果:

    <function timer.<locals>.deco at 0x00000182EEAE9EA0>
    in the test1
    the func run time is 3.000403881072998
    the func run time is 3.003307342529297

     实例二

    import time
    
    def timer(func):
        def deco():
            start_time = time.time()
            func()                   ###这里即执行 test1函数(func=test1)        stop_time = time.time()
            print ("the func run time is %s" % (stop_time-start_time))
        return deco
    
    @timer                         ### 等于 timer(test1),此时test1为一个内存对象
    def test1():
        time.sleep(3)
        print ("in the test1")

    test1()

    打印结果:
    in the test1
    the func run time is 3.0003435611724854

    带参数的装饰器

    带参数的装饰器即为在要被装饰的的函数里传入参数。例:

    #所有参数可用*args,**kwargs代替

    import
    time def timer(func): def deco(arg1): start_time = time.time() func(arg1) ###这里相当于执行test2(‘aaa’) stop_time = time.time() print ("the func run time is %s" % (stop_time-start_time)) return deco ##返回deco的内存地址 @timer def test2(aa): ##相当于将test2函数作为实参传给timer,即test2=timer(test2),test2=func ,func声明了deco函数,但没有执行,此时返回了deco的内存地址(deco加上括号“()”即可执行,所以test2()=deco()),
                    #所以 test2()传入一个参数执行等于deco()传入一个参数执行,
    time.sleep(2) print ('in the test2 %s ' % aa) #r1 = timer(test2) #r1("bb")     ##根据上面说明,r1的结果为deco的内存地址,r1()执行就等于 deco()执行 test2('aaa') ##test2(‘aaa’) 即等于 deco(‘aaa’),所以deco函数也要加上参数

    打印结果

    in the test2 aaa 
    the func run time is 2.0001180171966553

    装饰器内部参数判断

    #_*_coding:utf-8_*_
    
    
    user_status = False #用户登录了就把这个改成True
    
    def login(auth_type): #把要执行的模块从这里传进来
        def auth(func):
            def inner(*args,**kwargs):#再定义一层函数
                if auth_type == "qq":
                    _username = "alex" #模拟这是DB里存的用户信息
                    _password = "abc!23" #模拟这是DB里存的用户信息
                    global user_status
    
                    if user_status == False:
                        username = input("user:")
                        password = input("pasword:")
    
                        if username == _username and password == _password:
                            print("welcome login....")
                            user_status = True
                        else:
                            print("wrong username or password!")
    
                    if user_status == True:
                        return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能
                else:
                    print("only support qq ")
            return inner                   #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数
    
        return auth
    
    def home():
        print("---首页----")
    
    @login('qq')
    def america():
        #login() #执行前加上验证
        print("----衣服专区----")
    
    def japan():
        print("----化妆品专区----")
    
    @login('weibo')
    def henan(style):
        '''
        :param style: 喜欢看什么类型的,就传进来
        :return:
        '''
        #login() #执行前加上验证
        print("----河南专区----")
    
    home()
    # america = login(america) #你在这里相当于把america这个函数替换了
    #henan = login(henan)
    
    # #那用户调用时依然写
    america()
    
    # henan("3")

    实例二

    import time
    
    def timer(auth_type):
        def warpper(func):
            def deco(*args,**kwargs):
                if auth_type == "local":
                    print ("welcome to local auth %s" % auth_type)
                    start_time = time.time()
                    func()
                    stop_time = time.time()
                    print ("the func run time is %s" % (stop_time-start_time))
                else:
                    print ("ni da ye de %s" % auth_type)
            return deco
        return warpper
    
    @timer(auth_type="ldap") ### 等于 test1=timer(test1)    这里timer加上了括号并传了参数,会将auth_type的值传给timmer函数,然后会执行warpper(),
    # 此时还没有调用(需要在最下面调用test1和test2的时候才会调用执行)
    def test1():
        time.sleep(3)
        print ("in the test1")
    
    
    @timer(auth_type="local")                    ##这里的参数为作装饰器函数的参数
    def test2():
        print ("in the test2")
    
    test1()
    test2()
    
    
    打印结果:
    ni da ye de ldap
    welcome to local auth local
    in the test2
    the func run time is 0.0

    双层装饰器

    实例

    user_info = {}
    
    def check_login(func):                                                            #### 检查是否的登陆
        def inner(*args,**kwargs):            
            if user_info.get('is_login',None):                                        ####字典的get方法
                r = func(*args,**kwargs)
                return r
            else:
                print ("please login")
        return inner
    
    
    def check_admin(func):                                                            ####检查是否是admin权限
        def inner(*args,**kwargs):
            if user_info.get('user_type',None) == 2:                                ###2为管理员权限
                r = func(*args,**kwargs)
                return r
            else:
                print("perssion deined")
        return inner
    
    @check_login                                                                    ###双层装饰器
    @check_admin                                                                    ###双层装饰器
    def index():      ###manage user login
        print ('welcome')
    
    @check_login
    def home():                                                                     ###普通用户登陆
    
    def login():
        c = input('user:')
        if c == 'admin':
            user_info['is_login'] = True
            user_info['user_type'] = 2
        else:
            user_info['is_login'] = True
            user_info['user_type'] = 1
    
    
    def main():
        while True:
            a = input("1:denglu ,2:chakan xinxi ,3:super manager ")
            if a == "1":
                login()
            elif a == "2":
                home()
            elif a == "3":
                index()
    
    main()
    
    
    执行说明:
    在双层装饰器 处,从上往下执行,即,先执行@check_login加载到内存,在执行@check_admin,加载到内存,然后执行index函数
    解析顺序(从下往上):
    将@check_admin 和index函数作为一个参数传到@check_login函数下,即 check_login(func)下的func参数为 check_admin 和index函数 这个整体,
    然后顺序执行,如果check_login的条件满足了(满足已经登陆了),在执行check_admin函数(是否满足为admin用户),如果check_admin函数也满足了,则执行index函数(执行index)
  • 相关阅读:
    oracle常用命令(比较常见好用)
    vim编辑器详解
    对话框和打印控件
    winform弹出唯一的窗体
    ListView
    菜单栏和布局
    窗体属性和公共控件
    ASPCMS和WPF
    MVC
    正则表达式
  • 原文地址:https://www.cnblogs.com/FRESHMANS/p/8698316.html
Copyright © 2011-2022 走看看