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

  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/songcheng/p/7051229.html
Copyright © 2011-2022 走看看