文档章节

python装饰器

eddy_linux
 eddy_linux
发布于 2015/11/24 10:03
字数 937
阅读 47
收藏 1
点赞 0
评论 0
def f1():
    print "f1"
	f1() #表示函数执行f1   #表示函数,指向内存地址
 f1 = lambda x: x + 1 f1() # 执行这个lambda表达式,而不再是原来的f1函数,因为函数f1被重新定义了
装饰器代码剖析:
假如有这么一个需求,公司临时规定将某块业务加上访问权限,因为代码太多,又不想改变原有已经封装好的
代码,于是乎,基础平台的同志们想出了这么一个解决办法:利用装饰器解决
那么什么是装饰器?这个问题先留着,直接看代码:(代码剖析:)
def auth_login(func):    # func = f1 ,func() = f1()
    def inner():
        print "welcome to login ..."     #验证的内容加在这里 
        func()           # func() = f1() #相当于执行f1()
    reture inner         # 返回 inner函数体
	def f1():
    #print "welcome to login ..."  #需求是在这块加上验证(那么怎么实现?)
    print "f1..."
	result = auth_login(f1)            #等于inner函数(包括它下面那一段代码)f1 = result
f1()  #函数执行
上面代码梳理:
基础平台代码:(在业务平台不需要修改调用方式的时候,直接调用基础平台这块代码)
bash.py #代码名称
def auth_login(func):
    def inner(*arg,**kwargs)
        print "welcome to login..."
        temp = func(*arg,**kwargs)
        print "login after..."
        return temp
    return inner
		
@auth_login
def fetch_server_list():
    server_list = ['server1','server2','server3']
    return server_list
执行业务程序 yw.py 结果如下:
import base
server_list = base.fetch_server_list('test')print server_list
程序执行结果:
welcome to login...login after...['server1', 'server2', 'server3']
上面的列子说了这么多,好,现在我们来做一个用户登陆验证:
def login():   # 这里定义一个login 函数
    name = "Allen"   # 如果这里是“Allen“,则下面的函数调用,验证成功,否则失败
    if name == "Allen":        return True
    else:        return Falsedef auth_login(func):
    def inner(*arg,**kwargs):  
        is_login = login()    #这里加入一个验证判断
        if not is_login:            print "非法用户"

        print "welcome to login..."
        temp = func(*arg,**kwargs)        print "login after..."
        return temp    return inner@auth_logindef fetch_server_list(arg):
    server_list = ['server1','server2','server3']    return server_list
执行业务程序 yw.py 结果如下:
import base
server_list = base.fetch_server_list('test')print server_list
函数执行结果:
welcome to login...login after...['server1', 'server2', 'server3']
如果name = ”aaaa“, 不是”Allen“,则执行结果:验证失败:
非法用户
welcome to login...login after...['server1', 'server2', 'server3']
那么又有人问,这个有个鸟用,我还需要密码验证,那么这个怎么做呢?
少废话,直接上代码:
def login(key):
    local_key = "123456"   #这里做个一个key验证
    if local_key == key:        return True
    else:        return False
	
	def auth_login(func):
    def inner(*arg,**kwargs):
        #key = kwargs['token']     #注意这里
        #del kwargs['token']
        key = kwargs.pop('token')  #这一句等于 上面注释的两句 #这句含义:因为下面的login 只接受一个参数,这里多一个参数,所有删除
        is_login = login(key)      #注意这里
        if not is_login:            print "非法用户"
	
        print "welcome to login..."
        temp = func(*arg,**kwargs)        print "login after..."
        return temp   
    return inner	
@auth_logindef fetch_server_list(arg):
    server_list = ['server1','server2','server3']    return server_list
执行业务程序 yw.py 结果如下:
import base
server_list = base.fetch_server_list('test',token=‘key1111’)  #注意这里print server_list
多装饰器:
@auth_login@auth_logindef f1():
    pass
	执行的结果:
就是一层套一层
双装饰用途:
双层装饰器,可以用在以下途径:
比如用户权限管理,第一层装饰器用于用户名密码验证,
第二层用在 判断用户是什么身份的用户,比如:普通用户,超级用户等
需求:
需求又来了,在上面获取 fetch_server_list 之前执行一个函数,
可不可以在fetch_server_list 之后再执行一个函数?
作业1:
将如下三层装饰器用语言解释一遍:
#!/usr/bin/env python#coding:utf-8
  def Before(request,kargs):
    print 'before'
      def After(request,kargs):
    print 'after'
  
  def Filter(before_func,after_func):
    def outer(main_func):
        def wrapper(request,kargs):
              
            before_result = before_func(request,kargs)            if(before_result != None):                return before_result;
              
            main_result = main_func(request,kargs)            if(main_result != None):                return main_result;
              
            after_result = after_func(request,kargs)            if(after_result != None):                return after_result;              
        return wrapper    return outer      
@Filter(Before, After)def Index(request,kargs):
    print 'index'


© 著作权归作者所有

共有 人打赏支持
eddy_linux
粉丝 18
博文 135
码字总数 188789
作品 0
成都
程序员

暂无相关文章

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 43分钟前 ⋅ 0

Python模块/包/库安装(6种方法)

Python模块/包/库安装(6种方法) 冰颖机器人 2016-11-29 21:33:26 一、方法1: 单文件模块 直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip...

cswangyx ⋅ 今天 ⋅ 0

零基础学习大数据人工智能,学习路线篇!系统规划大数据之路?

大数据处理技术怎么学习呢?首先我们要学习Python语言和Linux操作系统,这两个是学习大数据的基础,学习的顺序不分前后。 Python:Python 的排名从去年开始就借助人工智能持续上升,现在它已经...

董黎明 ⋅ 今天 ⋅ 0

openJdk和sun jdk的区别

使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的OpenJDK, 那么到底什么是OpenJDK,它与SUN JDK有什么关系和区别呢? 历史上的原因是,Ope...

jason_kiss ⋅ 今天 ⋅ 0

梳理

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 它是JS的状态容器,是一种解决问题的方式,所以即可以用于 react 也可以用于 vue。 需要理解其思想及实现方式。 应用中所有的 stat...

分秒 ⋅ 今天 ⋅ 0

Java 后台判断是否为ajax请求

/** * 是否是Ajax请求 * @param request * @return */public static boolean isAjax(ServletRequest request){return "XMLHttpRequest".equalsIgnoreCase(((HttpServletReques......

JavaSon712 ⋅ 今天 ⋅ 0

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争...

码代码的小司机 ⋅ 今天 ⋅ 0

到底会改名吗?微软GVFS 改名之争

微软去年透露了 Git Virtual File System(GVFS)项目,GVFS 是 Git 版本控制系统的一个开源插件,允许 Git 处理 TB 规模的代码库,比如 270 GB 的 Windows 代码库。该项目公布之初就引发了争...

linux-tao ⋅ 今天 ⋅ 0

笔试题之Java基础部分【简】【二】

1.静态变量和实例变量的区别 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变...

anlve ⋅ 今天 ⋅ 0

Lombok简单介绍及使用

官网 通过简单注解来精简代码达到消除冗长代码的目的 优点 提高编程效率 使代码更简洁 消除冗长代码 避免修改字段名字时忘记修改方法名 4.idea中安装lombnok pom.xml引入 <dependency> <grou...

to_ln ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部