python - Decorator, Iterator

Catalog

1 Decorator

1.1 Purpose, application scenario:

  • Purpose:

    Without changing the internal code of the original function, the function is customized before and after execution.

  • Application scenarios:

    When you want to extend functions, you can choose to use decorators.

1.2 Writing Decorators and Applications

    1. Basic Decorator

      # Decorator Format (Double Nested Functions)
      def outer layer function (parameter):
         def inner function (* arg,**kwarg)
             return parameter (* arg,**kwarg)
         return inner function
      
      # Application Format of Decorator
       @ Outer Layer Function
       The function to be decorated by def ()
         pass
      
      # Execution function, automatic trigger decorator
       Functions to decorate ()

      Exercises

      def func(arg):
          def inner():
              print('before')
              v = arg()
              print('after')
              return v 
          return inner 
      
      def index():
          print('123')
          return '666'
      
      
      # Example 1
      v1 = index() # Execute the index function, print 123 and return 666 to assign to v1.
      
      # Example 2
      v2 = func(index) # v2 is inner function, arg=index function
      index = 666 
      v3 = v2()
      
      # Example 3
      v4 = func(index)
      index = v4  # index ==> inner 
      index()
      
      # Example 4
      index = func(index)
      index()
      def func(arg):
          def inner():
              v = arg()
         return v 
          return inner 
      
      # Step 1: Execute the func function and pass the following function parameters, equivalent to: func(index)
      # Step 2: Reassign the return value of func to the following function name. index = func(index)
      @func 
      def index():
          print(123)
          return 666
      
      print(index)
      # Calculate function execution time
      
      def wrapper(func):
        def inner():
              start_time = time.time()
              v = func()
              end_time = time.time()
              print(end_time-start_time)
              return v
          return inner
      
      @wrapper
      def func1():
          time.sleep(2)
          print(123)
      @wrapper
      def func2():
          time.sleep(1)
          print(123)
      
      def func3():
          time.sleep(1.5)
          print(123)
      
      func1()

      Note: Question: Why add * arg,** kwarg

      Understand:

  • Variable assignment

    ```python
    def func():
    print(1)

    v1 = func
    func = 666
    ```

    • Look at what exactly is return ed?

    • I have to find my own, I did not go to the scope of the higher level to find.

Reception:

python @xx # index = xx(index) def index(): pass index()

    1. On parameters

      def x(func):
          def inner(a1):
              return func(a1)
          return inner 
      
      @x
      def index(a1):
         pass
      def x(func):
          def inner(a1,a2):
              return func(a1,a2)
          return inner 
      
      @x
      def index(a1,a2):
         pass
      
      # index = inner
      index(1,2)
      
      # ################################### The purpose of parameter unification is to transfer parameters to the original index function.
      def x(func):
          def inner(a1,a2):
              return func()
          return inner 
      
      @x
      def index():
         pass
      # func = original index function u
      # index = inner
      index(1,2)

      What if you write a unified decorator for several functions?

      def x1(func):
          def inner(*args,**kwargs):
              return func(*args,**kwargs)
          return inner 
      
      @x1
      def f1():
          pass
      
      @x1
      def f2(a1):
          pass
      @x1
      def f3(a1,a2):
          pass 

      Decorator Suggested Writing:

      def x1(func):
          def inner(*args,**kwargs):
              data = func(*args,**kwargs)
              return data
          return inner 
    1. Decorator with parameters

      # Step 1: Execute v1 = uuu(9)
      # Step 2: ret = v1(index)
      # Step 3: index = ret 
      @uuu(9)
      def index():
          pass
      # ################## Ordinary ornaments #####################
      def wrapper(func):
          def inner(*args,**kwargs):
              print('Before calling the original function')
              data = func(*args,**kwargs) # Execute the original function and get the return value
              print('After the caller function')
              return data
          return inner 
      
      @wrapper
      def index():
          pass
      
      # ################## Decorator with parameters #####################
      def x(counter):
          def wrapper(func):
              def inner(*args,**kwargs):
                  data = func(*args,**kwargs) # Execute the original function and get the return value
                  return data
              return inner 
         return wrapper 
      
      @x(9)
      def index():
          pass

      Exercises

      # Write a decorator with parameters, realize: how many parameters, how many times will the decorated function be executed, add each result to the list, and finally return to the list.
      def xxx(counter):![](https://img2018.cnblogs.com/blog/1646753/201907/1646753-20190719213053775-1588807446.png)
      
      
          print('x function')
          def wrapper(func):
              print('wrapper function')
              def inner(*args,**kwargs):
                  v = []
                  for i in range(counter):
                      data = func(*args,**kwargs) # Execute the original function and get the return value
                      v.append(data)
                  return v
              return inner
          return wrapper
      
      @xxx(5)
      def index():
          return 8
      
      v = index()
      print(v)
      
      # Write a decorator with parameters to achieve: how many parameters, how many times the decorated function will be executed, and return the results of the last execution.
      def xxx(counter):
          print('x function')
          def wrapper(func):
              print('wrapper function')
              def inner(*args,**kwargs):
                  for i in range(counter):
                      data = func(*args,**kwargs) # Execute the original function and get the return value
                  return data
              return inner
          return wrapper
      
      @xxx(5)
      def index():
          return 8
      
      v = index()
      print(v)
      # Write a decorator with parameters to achieve: how many parameters, how many times the decorated function will be executed, and return the maximum value of the execution results.
      def xxx(counter):
          print('x function')
          def wrapper(func):
              print('wrapper function')
              def inner(*args,**kwargs):
                  value = 0
                  for i in range(counter):
                      data = func(*args,**kwargs) # Execute the original function and get the return value
                      if data > value:
                          value = data 
                  return value
              return inner
          return wrapper
      
      @xxx(5)
      def index():
          return 8
      
      v = index()
      print(v)
      def x(counter):
          print('x function')
          def wrapper(func):
              print('wrapper function')
              def inner(*args,**kwargs):
                  if counter:
                      return 123
                  return func(*args,**kwargs)
              return inner
          return wrapper
      
      @x(True)
      def fun990():
          pass
      
      @x(False)
      def func10():
          pass

2 iterator

I can't write iterators myself, just use them.

Task: Please show all the data in the list.

    1. while + Index + Counter

    2. Iterator, one by one acquisition of elements in an object (an object created by the str/list/tuple/dict/set class) - an iterative object

      Representation: Has _ next _ method and obtains elements in the iteratable object (one before and one after each call).

        1. First convert an object (such as a list) into an iterator

          v1 = iter([11,22,33,44])

          v1 = [11,22,33,44]_ _ iter _ ()

        2. The iterator wants to get each value: repeated calls (val = v1. next ())

          v1 = [11,22,33,44]
          
          # List conversion to iterator
          v2 = iter(v1)
          result1 = v2.__next__()
          print(result1)
          result2 = v2.__next__()
          print(result2)
          result3 = v2.__next__()
          print(result3)
          result4 = v2.__next__()
          print(result4)
          result5 = v2.__next__()   # v1 has only four elements, and the fifth acquisition will result in an error: StopIteration
          print(result5)
          
          v1 = "alex"
          v2 = iter(v1)
          while True:
              try:
                  val = v2.__next__()
                  print(val)
              except Exception as e:
                  break
        3. Until an error is reported: StopIteration error indicates that the iteration has been completed.

        4. How to judge whether an object is an iterative object: whether there are _ next _ methods in it.

    3. for loop:

      v1 = [11,22,33,44]
      
      # 1. Internally converts v1 into an iterator
      # 2. Internal repetitive iterator. _next_()
      # 3. Make no mistake after taking
      for item in v1:
          print(item)

3 Iterable Objects

    1. Internally has iter () method and returns an iterator

      v1 = [11,22,33,44]
      result = v1.__iter__()
    2. Can be cycled for

Keywords: Python

Added by apsomum on Sat, 24 Aug 2019 12:01:25 +0300