Fork me

python基础---闭包、装饰器

闭包、装饰器

注意:使用装饰器,最终都会改变装饰函数的函数名称及所属属性,所以在实际的装饰器中如果后续会涉及用到装饰函数函数名或所属属性的,需要加入python自带的模块@wraps确保函数装饰后,不会产生函数名及所属属性的改变。示例如下:

# 1 未加入@wraps装饰器
# coding=utf-8
from functools import wraps   
def my_decorator(func):    
	def wrapper(*args, **kwargs):        
		'''decorator'''        
		print('Decorated function...')        
		return func(*args, **kwargs)    
	return wrapper   
@my_decorator 
def test():    
	"""Testword"""     
	print('Test function')
print(test.__name__, test.__doc__)

# 打印结果:
"""
wrapper decorator
[Finished in 0.1s]
"""

# 2 加入@wraps装饰器
from functools import wraps   
def my_decorator(func):    
	@wraps(func)    
	def wrapper(*args, **kwargs):        
		'''decorator'''        
		print('Decorated function...')        
		return func(*args, **kwargs)    
	return wrapper

@my_decorator 
def test():    
	"""Testword"""     
	print('Test function')
print(test.__name__, test.__doc__)

# 打印结果:
"""
test Testword
[Finished in 0.1s]
"""

  • 闭包
        # 定义:在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
      
          def line_6(k, b):
          	def create_y(x):
          		print(k*x+b)
          	return create_y
          
          line_6_1 = line_6(1, 2)
          line_6_1(0)
          line_6_1(1)
          line_6_1(2)
          line_6_2 = line_6(11, 22)
          line_6_2(0)
          line_6_2(1)
          line_6_2(2)
      
          # 思考:函数、匿名函数、闭包、对象 当做实参时 有什么区别?
          # 1. 匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能
          # 2. 普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能
          # 3. 闭包能够将较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据
          # 4. 对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据
        
    
  • 装饰器
    • 不带参数的装饰器
          def set_func(func):
          	def call_func():
          		print("---这是权限验证1----")
          		print("---这是权限验证2----")
          		func()
          	return call_func
          
          @set_func  # 等价于test1 = set_func(test1) 
          def test1():
          	print("-----test1----")
      
          test1()
          
          # 打印结果:
          """
          ---这是权限验证1----
          ---这是权限验证2----
          -----test1----
          [Finished in 0.1s]
          """
      
      
    • 带参数的装饰器
      • 带一个参数
            def set_func(func):
            	def call_func(a):
            		print("---这是权限验证1----")
            		print("---这是权限验证2----")
            		func(a)
            	return call_func
            
            @set_func  # 相当于 test1 = set_func(test1)
            def test1(num):
            	print("-----test1----%d" % num)
        
            test1(100)
            
            # 打印结果:
            """
            ---这是权限验证1----
            ---这是权限验证2----
            -----test1----100
            [Finished in 1.3s]
            """
            ```
        - 带多个参数
            ```python
            def set_func(func):
            	print("---开始进行装饰")
            	def call_func(*args, **kwargs):
            		print("---这是权限验证1----")
            		print("---这是权限验证2----")
            		# func(args, kwargs)  # 不行,相当于传递了2个参数 :1个元组,1个字典
            		func(*args, **kwargs)  # 拆包
            	return call_func
            
            
            @set_func  # 相当于 test1 = set_func(test1)
            def test1(num, *args, **kwargs):
            	print("-----test1----%d" % num)
            	print("-----test1----" , args)
            	print("-----test1----" , kwargs)
            
            
            test1(100)
            test1(100, 200)
            test1(100, 200, 300, mm=100)
                
            # 打印结果:
            """
            ---开始进行装饰
            ---这是权限验证1----
            ---这是权限验证2----
            -----test1----100
            -----test1---- ()
            -----test1---- {}
            ---这是权限验证1----
            ---这是权限验证2----
            -----test1----100
            -----test1---- (200,)
            -----test1---- {}
            ---这是权限验证1----
            ---这是权限验证2----
            -----test1----100
            -----test1---- (200, 300)
            -----test1---- {'mm': 100}
            [Finished in 0.2s]
        
    • 通用类的装饰器
          # 通用类装饰器
          def set_func(func):
      	print("---开始进行装饰")
      	def call_func(*args, **kwargs):
      		print("---这是权限验证1----")
      		print("---这是权限验证2----")
      		# func(args, kwargs)  # 不行,相当于传递了2个参数 :1个元组,1个字典
      		return func(*args, **kwargs)  # 拆包
      	return call_func
      	
      	@set_func  # 相当于 test1 = set_func(test1)
          def test1(num, *args, **kwargs):
          	print("-----test1----%d" % num)
          	print("-----test1----" , args)
          	print("-----test1----" , kwargs)
          	return "ok"
      
          @set_func
          def test2():
          	pass
          
          ret = test1(100)
          print(ret)
          
          ret = test2()
          print(ret)
          
          # 打印结果:
          """
              
          """
          ```
      - 对带有返回值的函数进行装饰
      ```python
      def set_func(func):
      	print("---开始进行装饰")
      	def call_func(*args, **kwargs):
      		print("---这是权限验证1----")
      		print("---这是权限验证2----")
      		# func(args, kwargs)  # 不行,相当于传递了2个参数 :1个元组,1个字典
      		return func(*args, **kwargs)  # 拆包
      	return call_func
      
      
      @set_func  # 相当于 test1 = set_func(test1)
      def test1(num, *args, **kwargs):
      	print("-----test1----%d" % num)
      	print("-----test1----" , args)
      	print("-----test1----" , kwargs)
      	return "ok"
      
      @set_func
      def test2():
      	pass
      
      ret = test1(100)
      print(ret)
      
      ret = test2()
      print(ret)
          
      # 打印结果:
      # 装饰器使用return返回func,被装饰函数有return的返回return结果,没有发返回
      # 没有return的返回None,不影响实际的使用
      """
      ---开始进行装饰
      ---开始进行装饰
      ---这是权限验证1----
      ---这是权限验证2----
      -----test1----100
      -----test1---- ()
      -----test1---- {}
      ok
      ---这是权限验证1----
      ---这是权限验证2----
      None
      [Finished in 0.1s]
      """
      
    - 一个装饰器装饰多个函数
        ```python
            def set_func(func):
            	def call_func(a):
            		print("---这是权限验证1----")
            		print("---这是权限验证2----")
            		func(a)
            	return call_func
    
            @set_func  # 相当于 test1 = set_func(test1)
            def test1(num):
            	print("-----test1----%d" % num)
            
            @set_func  # 相当于 test2 = set_func(test2)
            def test2(num):
            	print("-----test2----%d" % num)
            
            test1(100)
            test2(200)
             
            # 打印结果:
            """
            ---这是权限验证1----
            ---这是权限验证2----
            -----test1----100
            ---这是权限验证1----
            ---这是权限验证2----
            -----test2----200
            [Finished in 0.2s]    
            """
        ```
    - 多个装饰器装饰一个函数
        ```python
            # 多个装饰器对一个函数进行装饰:
            def add_qx(func):
            	print("---开始进行装饰权限1的功能---")
            	def call_func(*args, **kwargs):
            		print("---这是权限验证1----")
            		return func(*args, **kwargs)
            	return call_func
            
            def add_xx(func):
            	print("---开始进行装饰xxx的功能---")
            	def call_func(*args, **kwargs):
            		print("---这是xxx的功能----")
            		return func(*args, **kwargs)
            	return call_func
            
            @add_qx
            @add_xx
            def test1():
            	print("------test1------")
            
            test1()
        
            # 打印结果:
            """
            ---开始进行装饰xxx的功能---
            ---开始进行装饰权限1的功能---
            ---这是权限验证1----
            ---这是xxx的功能----
            ------test1------
            [Finished in 0.1s] 
            """
            
            # 实例:
            def set_func_1(func):
            	def call_func():
            		# "<h1>haha</h1>"
            		return "<h1>" + func() + "</h1>"
            	return call_func
            
            def set_func_2(func):
            	def call_func():
            		return "<td>" + func() + "</td>"
            	return call_func
            
            
            @set_func_1
            @set_func_2
            def get_str():
            	return "haha"
            
            print(get_str())
            
            # 打印结果:
            """
            <h1><td>haha</td></h1>
            [Finished in 0.1s]
            """
        ```
    - 类装饰器
        ```python
            class Test(object):
            	def __init__(self, func):
            		self.func = func
            
            	def __call__(self):
            		print("这里是装饰器添加的功能.....")
            		return self.func()
            
            
            @Test  # 相当于get_str = Test(get_str)
            def get_str():
            	return "haha"
            
            print(get_str())  # 实际会调用__call__方法
                
            # 打印结果:
            """
            这里是装饰器添加的功能.....
            haha
            [Finished in 0.2s]
            """
        ```
    

posted @ 2018-11-05 11:09  achjiang  阅读(112)  评论(0)    收藏  举报