python 装饰器

瘦欲@ 提交于 2020-03-07 06:59:01

之前学习编程语言大多也就是学的很浅很浅,基本上也是很少涉及到装饰器这些的类似的内容。总是觉得是一样很神奇的东西,舍不得学(嘿嘿)。今天看了一下书籍。发现道理还是很简单的。

简单的说:装饰器主要作用就是对函数进行一些修饰,它的出现是在引入类方法和静态方法的时候为了定义静态方法出现的。例如为了把foo()函数声明成一个静态函数

1  class Myclass(object):2      def staticfoo():3          ............4          ............ 5      staticfoo = staticmethod(staticfoo)

可以用装饰器的方法实现:

1 class Myclass(object):2   @staticmethod  3   def staticfoo():4     .........5     .........

这个例子很明显很容易就可以看懂。

说到这里我们举一个下面的例子,这个例子里面同时涉及到一个重要内容,就是对于python中的函数的本质理解。

代码:

 1 # -*- coding: utf-8 -*- 2 from time import ctime 3 from time import sleep 4 def ftfunc(func): 5     def timef(): 6         print "[%s] %s() called" % (ctime(),func.__name__) 7         return func() 8     return timef 9 10 @ftfunc11 def foo():12     print 'hello'13 14 if __name__ == '__main__':15     16     foo()17     sleep(2)18 19     for i in range(2):20         sleep(1)21         foo()

运行这段代码;我们可以看到终端依次会输出以下内容:

其中ftfunc函数是我们自己自定义的一个函数,这个函数是以一个函数作为参数的函数,这也就满足了作为一个装饰器的要求,根据上面我们对于装饰器的等价变换规则,这段代码

1  @ftfunc2  def foo():3      print 'hello'

可以转换成以下的代码:

1 def foo():2     print 'hello'3 4 foo = ftfunc(foo)

再结合上面原来的代码我们很快就可以体会到了装饰器的作用。

但是我在编写这段代码的时候,有一个地方打错了:

这段代码:

1     return func()2 return timef

被我写成了:

1     return func2 return timef

于是输出结果就是不一样,后来终于发现了一个重要的概念:"foo"是函数对象的引用,而"foo()"是函数对象的调用。关于对象引用是python的重要的基础概念,在python中一切都是对象,同时类型是属于对象,而不是变量。一切的变量只是对象的引用,相当于让这个变量指向这个对象。“foo”正好可以理解成一个变量,只不过是它指向一个函数的对象。而“foo()”是函数对象的调用,即调用这个对象,是要执行这个函数的功能的。这里需要慢慢理解品味。基于此:

这样的一段代码运行结果和刚才是一模一样的。注意比较与刚才那段代码的不同之处,更加有利于理解。

 1 # -*- coding: utf-8 -*- 2 from time import ctime 3 from time import sleep 4 def ftfunc(func): 5     def timef(): 6         print "[%s] %s() called" % (ctime(),func.__name__) 7         return func 8     return timef 9 10 @ftfunc11 def foo():12     print 'hello'13 14 if __name__ == '__main__':15     16     foo()()17     sleep(2)18 19     for i in range(2):20         sleep(1)21         foo()()

此代码运行结果:

其实还可以分别对返回的timef函数加上括号,看看结果会是怎么样的。可以更好理解python中函数的概念。

1 # -*- coding: utf-8 -*-
2 from time import ctime
3 from time import sleep
4 def ftfunc(func):
5     def timef():
6         print "[%s] %s() called" % (ctime(),func.__name__)
7         return func()
8     return timef
9
10 @ftfunc
11 def foo():
12     print 'hello'
13
14 if __name__ == '__main__':
15    
16     foo()
17     sleep(2)
18
19     for i in range(2):
20         sleep(1)
21         foo()

运行这段代码;我们可以看到终端依次会输出以下内容:

其中ftfunc函数是我们自己自定义的一个函数,这个函数是以一个函数作为参数的函数,这也就满足了作为一个装饰器的要求,根据上面我们对于装饰器的等价变换规则,这段代码

1  @ftfunc2  def foo():3      print 'hello'

可以转换成以下的代码:

1 def foo():2     print 'hello'3 4 foo = ftfunc(foo)

再结合上面原来的代码我们很快就可以体会到了装饰器的作用。

但是我在编写这段代码的时候,有一个地方打错了:

这段代码:

1 
return func()
2 returntimef

 

被我写成了:

1     return func
2 return timef

于是输出结果就是不一样,后来终于发现了一个重要的概念:"foo"是函数对象的引用,而"foo()"是函数对象的调用。关于对象引用是python的重要的基础概念,在python中一切都是对象,同时类型是属于对象,而不是变量。一切的变量只是对象的引用,相当于让这个变量指向这个对象。“foo”正好可以理解成一个变量,只不过是它指向一个函数的对象。而“foo()”是函数对象的调用,即调用这个对象,是要执行这个函数的功能的。这里需要慢慢理解品味。基于此:

这样的一段代码运行结果和刚才是一模一样的。注意比较与刚才那段代码的不同之处,更加有利于理解。

 1 # -*- coding: utf-8 -*- 2 from time import ctime 3 from time import sleep 4 def ftfunc(func): 5     def timef(): 6         print "[%s] %s() called" % (ctime(),func.__name__) 7         return func 8     return timef 9 10 @ftfunc11 def foo():12     print 'hello'13 14 if __name__ == '__main__':15     16     foo()()17     sleep(2)18 19     for i in range(2):20         sleep(1)21         foo()()

此代码运行结果:

其实还可以分别对返回的timef函数加上括号,看看结果会是怎么样的。可以更好理解python中函数的概念。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!