Black Horse Programmer -Foundation framework NSFileManager introduction and usage

2023-01-19   ES  


Generally speaking, the role of the decorator isUnder the premise of not modifying the source code and call method of the decorative object, add additional functions to the decorative object

Decoles are often used for: inserting logs, performance testing, transaction processing, cache, permissions verification and other scenarios.

With a decorator, you can draw a lot of similar code that has nothing to do with the function function itself and continueReuse

Software design should followOpen and closed principles, that is, the extension is open, and the modification is closed.

After the software design is completed, you don’t want to change some source code and want to add new features.

The

function decorative device is divided into: non -cucumber decorations and ginseng decorations. The implementation principle of the two is the combination of “function nested+closure+function object”.

closure, also known as lexical closure or function closures, isReference to the function of free variables

The referenced free variable will exist with this function, even if it has left the environment that creates it.

def print_msg():  # Print_msg is the peripheral function
    msg = "I'm closure"

    def printer():  # Printer is the nested function
        print(msg)
    return printer

closure = print_msg()  # What I get here is a closed package
closure()  # output I'm Closure

MSG is a local variable that does not exist after the Print_MSG function is executed.

But the nested function quotes this variable and closed this local variable in the nested function, so that a closure is formed.

grammar candy(Syntactic Sugar) is also translated as a sugar -coated syntax, referring to a syntax added to the computer language.

This grammar does not affect the function of language, but it is more convenient for programmers to use.

Usually speaking with grammar sugar canInitability of programs, thereby reducing the chance of the program code errors.

@ Symbol is the syntax of the decoration. It placed in a function where the function starts (top of the head) and is binded with this function.

When we call this function, we will first pass this function as a parameter into its head, that is, the decorator.

below the decoration to calculate the execution duration of a function, allowing the function to sleep for 3 seconds.

# This is the decorative function
def timer(func):
    def wrapper(*args, **kw):
        start_time = time.time()
        func(*args, **kw)  # This is where the function is really executed
        stop_time = time.time()
        cost_time = stop_time - start_time
        print("Spending time: {} seconds".format(cost_time))
    return wrapper

import time

@timer
def want_sleep(sleep_time):
    time.sleep(sleep_time)

want_sleep(3)

Decorator When implementing it, the decorative function is actually another function (function names and other functions will change).

In order not to affect, the Python’s Functools package provides a namewrapsThe decorator to eliminate such side effects.

When writing a decorator, it is best to add wraps in Functools before implementation, which can retain the name and document string of the original function.

document stringis used to explain the document program to help program documents easier and easier to understand.

can use a pair of three single quotes’ ” or a pair of three dual quotes “” “” “” “” “” “” “” “to define the document string in the first line of the function body.

Usedoc(Pay attention to the dual subordinate line) Call the document string attribute in the function.

  1. Do not use @WRAPS decorations
def decorator(func):
    """this is decorator __doc__"""

    def wrapper(*args, **kwargs):
        """this is wrapper __doc__"""
        print("this is wrapper method")
        return func(*args, **kwargs)
    return wrapper

@decorator
def test():
    """this is test __doc__"""
    print("this is test method")

print("__name__: ", test.__name__)
print("__doc__:  ", test.__doc__)

Running results:
name: wrapper
doc: this is wrapper doc

Analysis:
When decorating the test () method, it is actually

test = decorator(test)

Returns the reference of the Wrapper method, that is, to point the test to the Wrapper method, so call the test.name, actually wrapper.name

This causes later searchThe name and annotation of this methodThe name and annotation of the embedded function of the decorative device

  1. Use @WRAPS decorations to solve this problem
from functools import wraps


def decorator(func):
    """this is decorator __doc__"""

    @wraps(func)
    def wrapper(*args, **kwargs):
        """this is wrapper __doc__"""
        print("this is wrapper method")
        return func(*args, **kwargs)
    return wrapper

@decorator
def test():
    """this is test __doc__"""
    print("this is test method")

print("__name__: ", test.__name__)
print("__doc__:  ", test.__doc__)

Running results:
name: test
doc: this is test doc

A function can simultaneously define multiple decorations, such as:

@a
@b
@c
def f ():
    pass

The order of its execution isfrom the inside to the outside, first call the innermost decorative, and finally call the outermost decorative device, it is equivalent to:

f = a(b(c(f)))

The decorator can not only be a function, but also a class.

Based on the implementation of a decorator, it must be realizedcalland __init__ two built -in functions.

When you use @ Form to add the decorative to the function, this method will be called.

init: Receive the decorative function
call: Realize decorative logic.

class logger(object):
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kwargs):
        print("[INFO]: the function {func}() is running..." \
              .format(func=self.func.__name__))
        return self.func(*args, **kwargs)
        
@logger
def say(something):
    print("say {}!".format(something))
say("hello")

Run results:
[INFO]: the function say() is running…
say hello!

Example without parameters can only print Info -level logs.

When you need to print the logs such as Debug and Warning, you need to pass the parameters to the decorator, and specify the level of the function.

Tarmeter and non -parameter decorators are very different.

init: No longer accepting the decorative function, but receiving the passing parameters.
call: Receive the decorative function to achieve decorative logic.

class logger(object):
  def __init__(self, level='INFO'):
    self.level = level

  def __call__(self, func): # Accepting function
    def wrapper(*args, **kwargs):
      print("[{level}]: the function {func}() is running..."\
        .format(level=self.level, func=func.__name__))
      func(*args, **kwargs)
    return wrapper # Return function

@logger(level='WARNING')
def say(something):
  print("say {}!".format(something))

say("hello")

Specify the running results after the warning level:
[WARNING]: the function say() is running…
say hello!

Among them, Wrapper function:

1. Call the original function
2. Add new features to it

def template(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
        
    return wrapper

defThere are ginseng decorations(x,y,z):
    def outter(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    returnOutter 

 @有 有 有(1,y=2,z=3)
defThe decorative object():
    pass

above is a detailed explanation of the Python decorative device, I hope it will be helpful to everyone. If you have any questions, please leave me a message, I will reply to everyone as soon as possible. Thank you very much for your support for CSDN!

source

Related Posts

51NOD1819 Black and White Tree V2 [Tree Chain Section Seeking the Black Dot LCA and the Black and White Flip]

[Reprinted] Some controls of Android soft keyboard

java count sorting

Unity playback brick play game (simple)

Black Horse Programmer -Foundation framework NSFileManager introduction and usage

Random Posts

unity custom font new feature one

2 line code completion level pull -up list box

FLEX layout dictionary

Log4J2

jquery实现简单收缩菜单