当前位置: 首页 > news >正文

热水工程技术支持 东莞网站建设宁波关键词网站排名

热水工程技术支持 东莞网站建设,宁波关键词网站排名,网站如果建设,做网站公司起什么名字装饰器是什么呢? 我们先来打一个比方,我写了一个python的插件,提供给用户使用,但是在使用的过程中我添加了一些功能,可是又不希望用户改变调用的方式,那么该怎么办呢? 这个时候就用到了装饰器。…

装饰器是什么呢?

我们先来打一个比方,我写了一个python的插件,提供给用户使用,但是在使用的过程中我添加了一些功能,可是又不希望用户改变调用的方式,那么该怎么办呢?

这个时候就用到了装饰器。装饰器的原理是什么?我们接下来就一步一步看过来!

假如我们有一个home函数如下:

1 def home():
2     print 'this is the home page!'

而我们希望用户在访问home函数之前先验证一下权限,那么在不改变用户调用方法的情况下,就需要在home中调用一个login函数,就像这样:

1 def login(usr):
2     if usr == 'Eva_J':
3         return True
4 def home():
5     result = login()
6     if result:
7         print 'this is the home page!'

这样可以实现我们的需求,但是我们看到home的代码发生了很大的变化,所有的代码都要被包裹在一个if语句中,并且要进行缩进,这往往不是我们希望看到的。那么我们还可以怎么做呢?
首先我们看一个小栗子:

def home():print 'this is the home page!'print home

输出:<function home at 0x000000000219C978>

我们定义了一个home函数,但是并不使用home()调用它,而是让程序打印出home方法的地址。

那么我们再看这段代码:

 1 def login(usr):
 2     if usr == 'Eva_J':
 3         return True
 4 def wrapper(funcname):
 5     if login('Eva_J'):
 6         return funcname
 7 def home():
 8     print 'this is the home page!'
 9 
10 home = wrapper(home)
11 home()
输出的结果:this is the home page!

我们可以看到这段代码的点睛之笔就在这句:“home = wrapper(home)”,我们将home函数的地址当做参数传给了wrapper方法,在wrapper方法中进行验证,验证通过之后再将home方法的地址返回,这个之后再调用home,我们就在没有修改home方法的情况下,调用了home,是不是方便了很多?这就是装饰器的概念!
但是很快我们发现这种方法还是不好,因为用户必须加上那句点睛之笔的代码再执行原本想执行的home方法,于是在python中就规定装饰器可以这样使用:

 1 def login(usr):
 2     if usr == 'Eva_J':
 3         return True
 4 
 5 def wrapper(funcname):
 6     if login('aaa'):
 7         return funcname
 8 
 9 @wrapper
10 def home():
11   print 'this is the home page!'
12
13 home()

看到了吧,我们只需要在home方法上加上一个“@wrapper”,就可以省去原本在home()方法前写的那句话了,这样就方便了很多,而且也没有改变用户的调用方式。
然而,你有没有想过,怎么使用装饰器传递参数?

def home(usr):print 'this is the home page!'

 我们来看看下面的实现方法:

 1 def wrapper1(funcname):
 2     print 'funcname:',funcname
 3     def wrapper2(argv):
 4         if login(argv):
 5             print 'funcname:',funcname
 6             return funcname(argv)
 7         else:
 8             return error
 9     return wrapper2
10 
11 
12 def home(usr):
13     print 'this is the home page!'
14     print 'hello ,',usr
15 
16 home = wrapper1(home)
17 home('Eva_J')
输出的结果:
funcname: <function home at 0x00000000022CFAC8>
funcname: <function home at 0x00000000022CFAC8>
this is the home page!
hello , Eva_J

解决啦,我们实现了装饰器的传参,那么如果我想传多个参数,不确定的参数可不可以呢?当然可以啦,你就用动态传参就好了呀~~~

看到这里基本上普通青年就够用了。但是作为一个文艺小青年,你愿不愿意用一个晚上的时间,来刨一刨装饰器的祖坟?

先来看多个装饰器的应用。

 1 def wrapper1(func):
 2     def inner():
 3         print 'w1,before'
 4         func()
 5         print 'w1,after'
 6     return inner
 7 
 8 def wrapper2(func):
 9     def inner():
10         print 'w2,before'
11         func()
12         print 'w2,after'
13     return inner
14 
15 @wrapper2
16 @wrapper1
17 def foo():
18     print 'foo'
19 
20 foo()

运行结果:
w2,before
w1,before
foo
w1,after
w2,after

从上面这个例子我们可以看出,装饰器就像是一个俄罗斯套娃,把被装饰的方法当成最小的一个娃娃,封装在最内层,外面一层一层的嵌套装饰器。

接下来再看一个装饰器传递函数参数的例子:

 

 1 def Before(request):
 2     print 'before'
 3 
 4 def After(request):
 5     print 'after'
 6 
 7 def Filter(before_func,after_func):
 8     def outer(main_func):
 9         def wrapper(request):
10             before_result = before_func(request)
11             if(before_result != None):
12                 return before_result;
13             main_result = main_func(request)
14             if(main_result != None):
15                 return main_result;
16             after_result = after_func(request)
17             if(after_result != None):
18                 return after_result;
19         return wrapper
20     return outer
21 
22 @Filter(Before, After)
23 def Index(request):
24     print 'index'
25 
26 Index('example')

先上结果:
before
index
after

首先,index里我只是随便传了一个参数,并没有什么实际的意义,不要被迷惑了。接下来看看这段代码的执行过程:

看上面这张图,先来统一解释一下,代码前面的数字是python在执行Index之前做的事情,它将这段代码中函数的地址写入内存,方便之后在调用中可以一下子找到。

在装饰器这里有点绕,来来回回了好几次,我们解释一下从第3步往后的步骤,首先是在第3步这里,解释器发现了这个函数,并把它放进了内存里,然后第4步又读到了一个装饰器,它就从内存里找到装饰器的地址返回到了第5步这个装饰器的位置。继续往下读,第6步它又把发现了一个outer函数,于是欢欢喜喜的把outer函数的地址放进了内存里,然后就停止了,因为它很清楚它不是来执行outer的,所以它调过了这个函数并顺序执行了这个函数外面的第一句话:第7步,return outer。这个时候解释器发现这不就是刚刚记下了地址的那个方法么?它就又回来了之前的地址,找到了outer函数。。。就是这样,直到执行到第10步return wrapper,这里我没有写,其实它也是兴冲冲的回到了家wrapper方法那里的,但是它发现下面已经没有它需要记录地址的函数了。所以它把最后的这个wrapper函数的地址返回给了装饰器,也就是装饰器下面的index方法。

这个时候,好巧不巧的,我们在程序中调用了这个index方法,那么解释器就把我们领到wrapper那里开始执行了,在wrapper里我们可以使用外层函数传过来的方法参数Before和After,这其实就是装饰器参数祖坟里的秘密了。不要问我17\21\25步后面为什么没有执行,因为我们的函数都没有返回值呀!

ok,刨祖坟活动结束,关机,睡觉!

 参考文章:

http://www.cnblogs.com/wupeiqi/articles/4980620.html

http://www.lbrq.cn/news/2468323.html

相关文章:

  • 山西自助建站费用低品牌营销的概念
  • 南京企业自助建站系统安卓手机优化软件哪个好
  • 商城模板建站价格营销模式有几种
  • 曲靖网站建设搜索引擎优化seo公司
  • 券优惠网站如何做竞价推广方案
  • 实战营销型网站建设网络流量统计工具
  • 建设厅网站查询资质营销策划的八个步骤
  • 怎样可以查到做网站公司个人接外包项目平台
  • 桂林北站改造seo的英文全称是什么
  • php网站挂到linux服务器上应该这么做网络优化工程师有多累
  • 长春建站价格重庆整站seo
  • 做网站的大小百度代运营
  • 表白网址可以直接复制seo网站排名优化服务
  • iis搭建网站seo全称英文怎么说
  • 四川省住房城乡建设厅官网查询海洋seo
  • 自助建站的优点与缺点网站收录查询系统
  • 国外比较好的资源网站哪个平台可以随便发广告
  • 建设银行积分兑换网站新媒体seo培训
  • 新疆新疆网页设计网站建设建网站流程
  • 免费h5源码资源源码站百度一下网页版
  • 网站维护与推广seo网络优化平台
  • 创建一个网站的一般步骤要点做个公司网站多少钱
  • 汉字域名的网站培训seo去哪家机构最好
  • 江门网站建设推广平台it培训学校it培训机构
  • 网站怎么做图片放映效果打开一个网站
  • 定制级高端网站建设湖南seo优化推荐
  • 网站建设年度汇报文职培训机构前十名
  • 易名中国域名门户网站营销软文的范文
  • 沈阳做网站推广的公司网址搜索ip地址
  • 礼叮当 一家做创意礼品定制的网站禁止搜索引擎收录的方法
  • 告别配置混乱!Spring Boot 中 Properties 与 YAML 的深度解析与最佳实践
  • SpringBoot学习路径--SpringBoot的简单介绍和项目搭建
  • 【Docker项目实战】在Docker环境下部署go-file文件分享工具
  • 计算机算术4-整形乘法
  • Android补全计划 DrawerLayout使用
  • 从零开始的云计算生活——番外6,使用zabbix对中间件监控