zoukankan      html  css  js  c++  java
  • 闭包与装饰器

    一、闭包:

    1、外层函数内定义内置函数

    2、外层函数返回值为内层函数的函数名

    3、内层函数引用外层函数的非全局变量

    def fun(a):

      def wrapper():

        pass # 对外层函数非全局变量的引用

      return wrapper
    二、装饰器

    1)装饰器的作用:在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数添加新的功能

    2)python的开放封闭原则:软件实体应该是可扩展的,而不可修改的。也就是说,对于扩展是开放的,而对修改是封闭的。

    3)装饰器的应用场景:

      a.登录验证

      b.函数运行时间统计

      c.执行函数之前做准备工作

      d.执行函数后清理工作

    4)装饰器的实现

      a.闭包实现装饰器(常用)

      b.普通函数也能作为装饰器(不常用)

      c.类实现装饰器(常用)

    注:如果要通过装饰器去装饰类或者有返回值的函数时,一定在装饰器内部将类或者函数调用的结果返回。

    5)装饰器的原理

    @ddt   ====》此处实现的就是 test = ddt(test)

    def test():

      pass

    1、普通装饰器

    定义:

    def decorator(func):

      def wrapper(*args,**kwargs):

        # 此处为加上扩展功能

        res = func(*args,**kwargs)  #变量接收被装饰类或者有返回值的函数的返回值

        # 此处为加上扩展功能

        return res  # 如果被装饰的是类或者返回值的函数,那么内层函数一定要将这个返回值返回

      return wrapper

    2、装饰器装饰类

    1)闭包实现的装饰器

    def decorator(func):

      def wrapper(*args,**kwargs):

        print("------装饰器执行了--1---")

        obj = func(*args,**kwargs)   #======>此处是创建了一个对象,需要返回

        print("-----装饰器执行了---2---")

        return obj

      return wrapper

    @decorator               #=======》MyTest = decorator(MyTest)

    class MyTest:

      def  test_login(self):

        print("-----MyTest----test_login")

    m = MyTest()

    print(m)

    2)普通函数实现的装饰器(非闭包实现的装饰器去装饰类)

    动态的给类添加属性

    实现简单版的ddt

    ddt装饰器

    #myddt.py

    def ddt(cls):
    for name, value in list(cls.__dict__.items()):
    if hasattr(value, "DATA"):
    data = getattr(value, "DATA")
    for i in data:
    setattr(cls, "test_{}".format(i), value)
    return cls


    def data(test_data):
    def my_data(func):
    setattr(func, "DATA", test_data)
    return func
    return my_data
    #MyTest.py
    @ddt
    class MyTest(unittest.TestCase):
    @data([1, 2, 3, 4, 5])
    def test_login(self):
    print("这里是登录用例的测试")

    #run.py
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(MyTest)
    runner = unittestreport.TestRunner(suite)
    runner.run()


    3、带参数的的装饰器(三层)
    定义:
    def decorator(number1,number2...):
      def decorator_wrapper(func):
        def wrapper(*args,**kwargs):
          print("此处可以是对number各参数的引用")
          res = func(
    *args,**kwargs)
          print(
    "此处可以是对number各参数的处理")
          return res
        return wrapper

      return decorator_wrapper
    三层装饰器:
      1、最外层:接收的是装饰器的参数
      2、第二层:接收的是被装饰的函数或者类
      3、最内层:接收的是被装饰函数或者类的参数


    本文来自博客园,作者:%女王%,转载请注明原文链接:https://www.cnblogs.com/lynne-wu/p/15392075.html

  • 相关阅读:
    volley框架使用
    Insert Interval
    candy(贪心)
    Best Time to Buy and Sell Stock
    Best Time to Buy and Sell Stock III
    distinct subsequences
    edit distance(编辑距离,两个字符串之间相似性的问题)
    trapping rain water
    word break II(单词切分)
    sudoku solver(数独)
  • 原文地址:https://www.cnblogs.com/lynne-wu/p/15392075.html
Copyright © 2011-2022 走看看