• python3----练习题(装饰器)


        装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。也就是说装饰器的作用就是为已经存在的对象添加额外的功能。 当使用@将装饰器附加到函数上时,就会调用此方法。

    单层装饰器:

     1 def outer(func):
     2     def inner():
     3         print("hello")
     4         r = func()
     5         print("end")
     6         return r
     7     return inner
     8 @outer
     9 def f1():
    10     print("good!")
    11 
    12 
    13 f1()
    14 
    15 #1、执行outer函数,是将下面的函数名,当做outer函数的参数
    16 #2、将outer的返回值重新赋值给f1,意思就是f1 = outer的返回值

    双层装饰器:

    注:对参数数量不确定的函数进行装饰,参数用(*args,**kwargs),自动适应参数数量。

    和单层装饰器原理一样,只是在原有基础上又多了一个装饰器。示例:

     1 def outer1(func):
     2     def inner(*args,**kwargs):
     3         print("123")
     4         ret = func(*args,**kwargs)
     5         print("369")
     6         return ret
     7     return inner
     8 
     9 def outer2(func):
    10     def inner(*args,**kwargs):
    11         print("456")
    12         ret = func(*args,**kwargs)
    13         print("789")
    14         return ret
    15     return inner
    16 
    17 @outer1
    18 @outer2
    19 def f():
    20     return 'ok'
    21 
    22 
    23 r = f()
    24 print(r)
    25 
    26 #打印结果:
    27 123
    28 456
    29 789
    30 369
    31 ok
    32 
    33 # 1、执行outer2函数,将f作为outer2函数的参数,将f赋值给func
    34 # 2、得到返回值inner,重新赋值给f:f = inner  ==>  f() = inner()
    35 # 3、执行outer1函数,将整个inner函数作为outer1函数的参数
    36 # 4、得到返回值inner,再重新赋值给f:f == inner  ==> f() = inner()
    37 # 5、因为装饰器只有两层,就不用再执行下一个装饰器函数,如果更多层就继续循环以上程序过程
    38 # 6、下面就执行最终的inner函数,执行func函数时,就是执行最原始的f函数

    深入浅出理解python 装饰器

     

    之前就了解到了装饰器, 但是就会点皮毛, 而且对其调用方式感到迷茫,正好现在的项目我想优化,就想到了用装饰器, 因此深入研究了下装饰器.

    先看下代码:

     1 import time
     2 
     3 
     4 # 将函数作为参数传入到此方法....
     5 def timeif(func):
     6     def wrapper(arg):
     7         print("in wrapper() %s" % (arg))
     8         start = time.clock()
     9         func(arg)
    10         end = time.clock()
    11         print("used: %s %s" % (end-start, arg))
    12     return wrapper
    13 
    14 
    15 @timeif
    16 def foo(arg):
    17     print("in foo() %s" % (arg))
    18 
    19 
    20 if __name__ == '__main__':
    21     foo(" Hello ")  # 表示执行foo函数....

    我的疑惑就是明明return 的是一个函数名,按道理来讲,返回的就是一个函数地址啊!我理解有问题?随后上网查资料,又是闭包....但是我个人对它不感冒,随后自己分析,总结出了一段程序,看完你就知道原因了.
    程序:

     1 # coding=utf-8
     2 # 带参数的函数  返回一个函数地址就行....
     3 def funX(x):
     4     def funY():
     5         return x
     6     return funY
     7 
     8 
     9 # 不带参数的函数....
    10 def funX1():
    11     print("调用函数funX1")
    12 
    13     def funY1():
    14         print("调用函数funY1")
    15     return funY1
    16 
    17 
    18 if __name__ == '__main__':
    19     # print(funX(5)())  # 调用有参数的嵌套函数...
    20     
    21     print(funX1()())  # 调用无参数的嵌套函数...

    这和我们的装饰器不像吗?这就是我们的装饰器!因此,我们可以按照上面的程序来理解,也就是说它是首先确定参数个数,随后分别传入的,下面,我们来改写代码:

     1 # coding=utf-8
     2 import time
     3 
     4 
     5 # 将函数作为参数传入到此方法....
     6 def timeif(func):
     7     def wrapper(arg):
     8         print("in wrapper() %s" % (arg))
     9         start = time.clock()
    10         func(arg)
    11         end = time.clock()
    12         print("used: %s %s" % (end-start, arg))
    13     return wrapper
    14 
    15 
    16 # @timeif
    17 def foo(arg):
    18     print("in foo() %s" % (arg))
    19 
    20 
    21 if __name__ == '__main__':
    22     timeif(foo)(' Hello')

  • 相关阅读:
    备份与还原SQL Server 数据库
    ASP网站发布到IIS上注意问题
    MySQL相关积累
    C#中 让日历控件dateTimePicker1显示你想要的日期
    C#,右击鼠标,窗体出现在鼠标右边
    c#中combobox绑定数据库成功(方法二)
    java web 编写资料
    windows下使用gethostbyname函数报错无法解析的外部符号
    C语言中的作用域,链接属性和存储类型
    二级指针的用法
  • 原文地址:https://www.cnblogs.com/jonm/p/8303990.html
Copyright © 2020-2023  润新知