设为首页 收藏本站
查看: 1123|回复: 0

[经验分享] 【24】Python装饰器笔记

[复制链接]

尚未签到

发表于 2018-8-9 07:58:42 | 显示全部楼层 |阅读模式
  装饰器
  定义:本职是函数,(装饰其他函数)就是为其他函数添加附加功能。
  原则:
  1.不能修改被装饰的函数的源代码
  2.不能修改被装饰函数的调用的方式
  

先来一个直观感受  
import time
  
def timmer(func): ##
  def warpper(*args,**kwargs):
  start_time=time.time()
  func()  ##run  test1()
  stop_time=time.time()
  print("the func time is %s"%(start_time-stop_time))
  return warpper
  

  
@timmer  #@加函数名,即可调用函数
  
def test1():  ###源代码
  time.sleep(3)
  print("in the test1")
  

  
test1()
  

  实现装饰器的知识储备:
  1.函数即"变量"
  2.高阶函数
  3.嵌套函数(函数里面def声明一个函数叫嵌套函数,调用函数不叫嵌套)
  

下面进行一波实验:如下三种结果(验证1.函数即“变量”)  
A.输出报错没有bar函数
  
def foo():
  print("in the foo")
  bar()
  
foo()
  

  
B.成功
  
def bar():
  print("in the bar")
  
def foo():
  print("in the foo")
  bar()
  
foo()
  

  
C.输出报错,没找到定义的bar函数
  
def foo():
  print("in the foo")
  bar()
  
foo()
  
def bar():
  print("in the bar")
  

  在将函数即“变量”的时候,先讲下python内存存储变量的机制。
  当设定一个变量x=1时,内存看成一个大house,这时候大house会腾出一个房间将变量值1放入这个房间,并贴上x的门牌号。
  如果是x=1,y=x,那就是变量值1这个房间将会有两个门牌号,即x&y。如图所示:
  而在python内存的回收机制中,当你的房间没有门牌号时,它就会默认回收。这样可以节约空间。而当两个或多个变量值都一样时,它不会给你创建N个房间,而是同一个房间内贴上N个门牌号。
DSC0000.jpg

  凡是也有例外,有人就会说了,那就不会有没有变量名的变量了吗?这个在python中,还真有即匿名函数lambda。当lambda x:x*3,结果是占用的内存地址。
  这里的
  print(“in the poo”)
  bar()
  就是函数体相当于变量存放在内存中。poo()就是门牌号,当执行A时之所以会报错,就是因为没有找到bar的函数体。而C虽然定义了bar()但是定义的位置不对,函数都是从上往下读取,当执行poo()之前并没有定义,所以会报错找不到bar
DSC0001.jpg

  2.高阶函数(又分以下两种)
  

a:把一个函数名当做实参传递给另外一个函数  
import time
  
def bar():
  time.sleep(3)
  print("in the bar")
  

  
def test1(func):  ##根据test1(bar)的调用可以看出,这里的func = bar。这就是把bar函数名传递给func当test1的实参
  start_time=time.time()
  func() #run bar()
  stop_time=time.time()
  print("the func run time is %s"%(stop_time-start_time))
  

  
test1(bar)
  

  
b:返回值中包含函数名
  
import time
  
def bar():
  time.sleep(3)
  print("in the bar")
  
def test2(func):
  print(func)
  return func  #f返回bar的内存值
  

  
print(test2(bar))
  
t=test2(bar) #test2执行结果赋值给了t,相当于把bar(赋值给了t,当使用t()时,就是在执行bar函数
  
t()  #run bar()
  

  3.嵌套函数 (在一个函数体内用def声明一个函数叫嵌套。调用不叫嵌套)
  

#局部即变量  
def foo():
  def bar():
  print("in the bar")
  bar() ##想要输出print结果就需要一层层的调用
  
foo()
  

  
#局部作用和全局作用域的访问顺序
  
x=0
  
def boo():
  def daa():
  x=2
  def son():
  x=3
  print(x)
  son()
  daa()
  
boo()
  
猜测下这里的输出结果是:
  

  下面写个简单的装饰器。(高阶函数+嵌套函数=》装饰器)
  不设定函数实参
  

import time  
def timer(func):  ##func=test1=test2
  def deco():
  start_time=time.time()
  func()  ##func=test1 =test2
  stop_time=time.time()
  print("the funce run time is %s" %(stop_time-start_time))
  return deco
  

  
def test1():
  time.sleep(3)
  print("in the test1")
  

  
@timer
  
def test2():
  time.sleep(3)
  print("in the test2")
  
test1=timer(test1)
  
test1() ##-->deco
  
test2()
  

  当设定test实参时,可以这样写。deco() func()里面都直接*args,***kwargs不限量。如果具体某一个参数,那就可以修改为具体的。
  

import time  
def timer(func):
  def deco(*args,**kwargs):
  start_time=time.time()
  func(*args,**kwargs)
  stop_time=time.time()
  print("the funce run time is %s" %(stop_time-start_time))
  return deco
  

  
def test1():
  time.sleep(3)
  print("in the test1")
  

  
@timer #非固定参数name
  
def test2(name):
  time.sleep(3)
  print("in the test2",name)
  

  
test1=timer(test1)
  
test1() ##-->deco
  
test2("alex")
  

  模拟远端登录与本地登录试验:
  

user,passwd="alex","abc"  
def auth(auth_type):
  print("auth>>>",auth_type)
  def outer_wrapper(func):
  def wrapper(*args,**kwargs):
  print("*args,**kwargs",*args,**kwargs)
  if auth_type=="local":
  username=input("Input user: ").strip()
  password=input("Input password: ").strip()
  if username==user and password==passwd:
  print("\033[32;1mUser has passed authentication\033[0m")
  res=func(*args,**kwargs)
  return res
  else:
  exit("\033[31;1mIminvalid username or password\033[0m")
  elif auth_type=="ldap":
  print("不会")
  return wrapper
  return outer_wrapper
  
def index():
  print("welcome to index page")
  
@auth(auth_type="local")  ##本地验证登录
  
def home():
  print("welcome to home page")
  return  "from home"
  
@auth(auth_type="ldap")  ##远端验证登录
  
def dds():
  print("welcome to dds page")
  

  
index()
  
print(home())
  
dds()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-548869-1-1.html 上篇帖子: Python第十三堂课(并发) 下篇帖子: python2基础-列表,元组,字典
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表