zoukankan      html  css  js  c++  java
  • python函数下篇装饰器和闭包,外加作用域

    函数是第一类对象

    函数能够被当做对象传递,函数可以被赋值

    装饰器和闭包的基础概念

    装饰器是一种设计模式能实现代码重用,经常用于查日志,性能测试,事务处理等,抽离函数大量不必的功能。 装饰器:
    1、装饰器本身是一个函数,用于装饰其它函数:
    2、功能:增强被装饰函数的功能。

    装饰器需要遵循的原则

    1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被装饰函数的调用方式

    装饰器 = 高阶函数+函数嵌套+闭包

    高阶函数

    1.函数接受的参数是一个函数名 2.函数的返回值是一个函数名 3.只有上述条件满足一个就是高阶函数

    def foo():
        print('高阶函数实例,被调用的函数')
    
    def func(foo):
        print('调用上面的函数')
        foo()
    
    func(foo)

    把函数名当做参数传给高阶函数,高阶函数直接返回函数名

    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time = time.time()
        return func
        stop_time = time.time()
        print('函数%s运行时间是%s')%(func,stop_time - start_time)
    
    foo = timmer(foo)
    foo()

    高阶函数总结 1.函数接收的参数是一个函数名
    作用:在不修改函数源代码的前提下,为函数添加新功能
    不足:会改变函数的调用方式

    2.函数的返回值是一个函数名
    作用:不修改函数的调用方式
    不足:不能添加新功能

    嵌套函数

    def father(name):
        print('from father %s'%name)
        def son():
            print('from son')
            def grandson():
                print('from grandson')
            grandson()
        son()
    father('逗逼')

    闭包函数:函数在嵌套环境中,如果在内层函数里,对外层函数作用域中的变量进行引用,在外层函数返回后内层函数依然可以使用外层函数中的变量,这种变量就构成了内层函数可以使用的环境。所以闭包对隐藏状态,以及在函数对象和作用域中随意切换,一个函数可以发挥N种功用

    def f1(x):
    def f2(y):
    return y ** x
    return f2
    f1(4)
    
    f3=f1(3)
    type(f3)
    
    f3(4)
    
    def startPos(m,n):
    def newPos(x,y):
    print(''The old position is (%d,%d), and the new position is (%d,%d)"%(m,n,m+x,n+y))
    return newPos
    
    action = startPos(10,10)
    action(1,2)
    action(-1,3)
    
    #结果
    <function f1.<locals>.f2 at 0x02125270>
    <class 'function'>
    64
    The old position is (10,10),and the new position is (11,12)
    The old position is (10,10),and the new position is (9,13)

    无参装饰器

    无参装饰器 = 高级函数 + 函数嵌套 基本框架

    #这就是一个实现一个装饰器最基本的架子
    def time(func):
        def wrapper():
            func()
        return wrapper
    
    加上参数
    
    def timer(func):
        def wrapper(*args,**kwargs):
            func(*args,**kwargs)
        return wrapper
    
    加上功能
    
    import time
    def timer(func):
        def wrapper(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            stop_time = time.time()
            print('函数[%s],运行时间是[%s]'%(func,stop_time-start_time))
        return wrapper
    
    加上返回值
    
    import time
    def timer(func):
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res = func(*args,**kwargs)
            stop_time = time.time()
            print('函数[%s],运行时间是[%s]'%(func,stop_time-start_time))
            return res
        return wrapper
    
    使用装饰器
    
    def cal(arry):
        res = 0
        for in in array:
            res+=i
        return res
    cal = timer(cal)
    cal(range(10)
    
    语法糖@
    
    @timer 
    def cal()
        def cal(array):
          res=0
          for i in array:
              res+=i
          return res
     
      cal(range(10))
    
    有参装饰器
    
    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    current_user={'username':None,'login':False}
    def auth(auth_type='file'):
        def auth_deco(func):
            def wrapper(*args,**kwargs):
                if auth_type == 'file':
                    if current_user['username'] and current_user['login']:
                        res = func(*args,**kwargs)
                        return res
                    username = input('用户名:').strip()
                    passwd = input('密码:').strip()
                    for index,user_dic in enumerate(user_list):
                        if username == user_dic['name'] and passwd ==username['passwd']:
                            current_user['username'] =username
                            current_user['login']=True
                            res = func(*args,**kwargs)
                            return res
                            break
                    else:
                        print('用户名或者密码错误,重新登录')
                elif auth_type =='ldap':
                    print('登录成功')
                    res = func(*args,**kwargs)
                    return res
            return wrapper
        return auth_deco
    @auth(auth_type='ldap')
    def index():
        print('欢迎来到主页面')
    @auth(auth_type='ldap')
    def home():
        print('家目录')
    def shopping_car():
        print('购物车页面')
    def order():
        print('订单页面')
    index()
    home()

    作用域规则 每次执行执行一个函数时,就会创建新的局部命名空间。该命名空间代表一个局部环境,其中包含函数参数的名称和在函数体内赋值的变量名称。解析这些名称 时,解释器首先搜索局部命名空间、如何没有找到匹配的名称,它就会搜索全局命名空间。函数的全局命名空间始终是定义该函数的模块。如果解释器在全局命名空间中也找不到匹配值,最终会检查内置命名空间。如果仍然找不到,就会引发NameError异常 image

  • 相关阅读:
    [翻译角]Headline English: A Captain Should Be Pitch Perfect at a Multitude of Skills (ESLPOD Blog)
    CF735D Taxes 哥德巴赫猜想判定素数 进一步猜想
    CF735C 数论平衡树叶子节点的最大深度贪心斐波那契条件归一化
    萌新的旅行&hdu5681单调队列的应用前缀和线段树ST表倍增解法
    CF731C Socks并查集(森林),连边,贪心,森林遍历方式,动态开点释放内存
    玲珑杯1007-A 八进制大数加法(实现逻辑陷阱与题目套路)
    关于石子合并
    codeforces724-B. Batch Sort
    codeforces724-A. Checking the Calendar 日期题
    如何筛选人
  • 原文地址:https://www.cnblogs.com/songcheng/p/7051229.html
Copyright © 2011-2022 走看看