python dry goods sharing in the source code Era

Simple decorator 1.1.1. The simplest decoration behavior One of the characteristics of decorator is to add content on the basis of executing original...
1.1.1. The simplest decoration behavior
1.1.2. Perfect decoration behavior
1.1.3.python's decorator syntax sugar
1.2. Several forms of Python decorator
1.2.2. Decorated function has parameters
1.2.3. The decorated function has indefinite parameters and return values
1.2.4. Change the behavior of the decorator (pass parameters to the decorator)
1.2.5. Using classes to define decorators
1.3. Multi layer decoration
Simple decorator

1.1.1. The simplest decoration behavior

One of the characteristics of decorator is to add content on the basis of executing original function.
Let's take a simple example:
We can use it as a log printer, and we will inform you politely before executing the function
"Dear coder, I'm going to execute it"
You will also be informed of the coder after execution.
Isn't it fun?
So, how do we execute the original function?
✔ if you give the name of the original function to the decoration function, the decoration function will have the ability to execute the old function.

Old function, function to be decorated

def fun(): print('I'm an old function') def factory(old_fun): print('='*20) old_fun() print('='*20) factory(fun)

1.1.2. Perfect decoration behavior

❓ what are the other problems with the decoration?
◇ the original function needs to be called through the decoration factory. The business department that originally called this function will modify the code in a large area;
❓ so how to improve this problem?
How to design a way to execute decoration factory when calling without changing the original function name.
◇ old_name = factory(old_name)

def fun(): print("I am fun") def factory(a): def tmp(): print("="*10) a() print("="*10) return tmp fun = factory(fun) fun()

1.2. Several forms of Python decorator

1.2.1. Parameterless decorator
Demo1: add function when to run:

import time def time_fun(func): def my_time(): print(f" running at ") func() return my_time @time_fun def fun1(): print("+++++++++") fun1() time.sleep(2) fun1()

1.2.2. Decorated function has parameters

The core of decorator is that the behavior of internal function is renamed;
The form of internal function shall meet the form of original function;

import time def time_fun(func): def my_time(arg1): # Reserved interface in internal function print(f" running at ") func(arg1) # Original function transfer parameter return my_time @time_fun def fun1(arg1): print("+++++{}++++".format(arg1)) fun1(10) time.sleep(2) fun1(10)

1.2.3. The decorated function has indefinite parameters and return values

The original function has a return value, and the interior decoration function also receives the return value for return.
import time

def time_fun(func): def my_time(*args, **kwargs): print(f" running at ") func(*args, **kwargs) return my_time @time_fun def fun1(arg1, arg2, name): print("+++++{},{},{}++++".format(arg1, arg2, name)) fun1(10, 20, name='rocky') time.sleep(2) fun1(10, 20, name='jim')

1.2.4. Change the behavior of the decorator (pass parameters to the decorator)

In decorators, we also have a requirement. According to the different parameters passed in, the behavior of decorators will be different, so how to define this kind of decorator.
First, understand the syntax of decorators:

@time_fun def fun1(arg1, arg2, name): print("+++++{},{},{}++++".format(arg1, arg2, name)) //Name of raw material = name of decorator (name of raw material) @time_fun("itsource") def fun1(arg1, arg2, name): print("+++++{},{},{}++++".format(arg1, arg2, name)) fun1 = time_fun("itsource")(fun1)

In this way, it is necessary to ensure that the content returned by time Fu ("its source") is exactly the standard decorator.
import time

def time_fun(flags): def time_arg(func): def my_time(*args, **kwargs): print(f" running at ") print("the flags is {}".format(flags)) return func(*args, **kwargs) return my_time return time_arg @time_fun("itsource") def fun1(arg1, arg2, name): print("+++++{},{},{}++++".format(arg1, arg2, name)) fun1(10, 20, name='rocky') time.sleep(2) fun1(10, 20, name='jim')

1.2.5. Using classes to define decorators

❓ what is the executable?
The object space with call method is called executable object. Every function defined is equivalent to defining call method in space.
❓ how to use classes to implement decorators
@Test # fun = Test(fun)
def fun():
pass
The init method of Test should receive the name of the decorated function
Calling fun() actually calls the call method of Test class
class Test():
def init(self, fn):
self.old_fun = fn

def __call__(self,): ... ... # Decorative content ret = self.old_fun()

@Test
def fun(a, b, name):
pass
fun()

1.3. Multi layer decoration

In actual development, a primitive function can be decorated with multiple decoration functions, which is called multi-layer decoration.
For multi-layer decoration, understand the execution process.

def bold(fn): def wrapper(): return f'<b></b>' return wrapper def italic(fn): def wrapper(): return f'<i></i>' return wrapper @italic @bold def hello(): return 'Hello World' print(hello())

[results]:
<i><b>Hello World</b></i>
1.4. summary
The decorator is actually a function (callable object);
Receiving the name of an old function;
Returns the name of the new function;
Call the old function in the new function;

10 November 2019, 09:11 | Views: 10052

Add new comment

For adding a comment, please log in
or create account

0 comments