1, Definition of method
Methods are organized, reusable code snippets used to implement a single, or associated function.
This method can improve the modularity of application and the reuse rate of code.
Python provides many built-in methods, such as print().
You can also create your own methods, which are called user-defined methods.
2, Method parameters
1. There are various classifications of parameters on the Internet. Here we make a classification. There are only two parameters of the method
- Position parameters are assigned to the parameter name when the method is defined according to the order of input parameters
- Keyword parameter, in the form of key=value, is assigned to the parameter name when the method is defined, independent of order
Let's explain it in detail
def test(a, b=1, c=2, *args, **kwargs): print(a) print(b) print(c) print(args) print(kwargs)
When the test method is called in the following way
test(1,2,3,4,5,6)
output
1
2
3
(4, 5, 6)
{'y': 7}
Here, the six parameters become position parameters, which are assigned to the defined parameters in turn according to the order you enter. The difference is
a. The parameters B and C are explicitly defined, and the parameter names can be printed directly
Args is a variable parameter. A parameter with no explicitly defined parameter name after a, B and C is assigned to args in the form of tuple, which is essentially a location parameter
When the test method is called in the following manner
test(c=1,a=2,b=3,d=4,e=5)
output
2
3
1
()
{'d': 4, 'e': 5}
Here, a, B, C, D and e become keyword parameters
When outputting, the value is assigned according to the key instead of the input order
The explicitly defined a, B and C have their own values,
Kwargs is a variable parameter. The parameters explicitly defined after a, B and C are assigned to kwargs in the form of a dictionary, which is essentially a keyword parameter
In the above code, the difference between a and bc is that bc is given a default value, also known as a default parameter, so you can call the method without entering bc, but you must enter a
A can be a location parameter (Figure 1, 2) or a keyword parameter (3, 4, 5)
# correct test(1) # 1 test(1, b=1, c=1) # 2 test(a=1) # 3 test(a=1, b=1) # 4 test(b=1,c=1,a=2) # 5 # report errors test(b=2) # 6 test(b=2, c=1) # 7
From the perspective of calling, * args can be understood as location parameters and * * kwargs can be understood as keyword parameters
Without the indefinite parameters * args and * * kwargs, the location parameters and keyword parameters are more determined by the call, as long as the default parameters are guaranteed to be later
When calling, the implicit call is a location parameter, and the display call is a keyword parameter, which can be converted to each other
ps: it may not be accurate to use implicit and display here, but I can't think of a better word. I can understand it
Please note: the default parameter is mentioned above. The value of the default parameter must be an immutable object, which will be described below
When there are indefinite parameters * args and * * kwargs, location parameters and keyword parameters cannot be converted at will
2. Parameter sequence
Let's talk about the conclusion first. The location parameter must be in front of the keyword parameter
Therefore, when defining a method, the recommended parameter order
def test(a, b, c=100, *args, d=1, e=2, f, **kwargs): print(a) print(b) print(c) print(args) print(d) print(e) print(f) print(kwargs) test(1, 2, 3, 4, 5, d=10, e = 7, l=11, f=8, h=10)
The results are as follows
1
2
3
(4, 5)
10
7
8
{'l': 11, 'h': 10}
* args before (including) are location parameters, which are assigned in sequence and cannot be out of order
* args is followed by keyword parameters, regardless of order
In the above figure, parameter c is given a default value of 100 when it is defined, but the printed result is 3, which is replaced by the position parameter. Therefore, when * args is available, it is not recommended to set the default value for the position parameter, which will hardly take effect (Note: not necessarily)
When the parameter * args is not required, but you want to distinguish between location parameters and keyword parameters, you can use * to distinguish
def test(a, b, c=100, *, d=1, e=2, f, **kwargs): print(a) print(b) print(c) print(d) print(e) print(f) print(kwargs)
give the result as follows
1
2
3
10
7
8
{'l': 11, 'h': 10}
* It is only a separator here. It does not temporarily use the parameter position and cannot be called and inherited
ps: the parameter order here is the best order of my personal experience. However, in the python version, the default parameter appears to report an error after * args, which can be adjusted. However, the principle of parameter order is that each parameter entered can be obtained in the method without an error
3. Default parameters
When defining a method, the parameter defined in the form of key=value is the default parameter, and this value is called the default value
When calling a method, if the key is not entered, or the location parameter cannot overwrite the key, the default value is obtained in the method
However, it should be noted that the value of the default parameter must be an immutable object
Consider the following example:
def test(a=[]): a.append(1) print(a) test() test() test() test()
Operation results:
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
This is because when python assigns a value to a variable, it does not give the value itself, but a reference to the value. Each time parameter a is called, it accesses the same memory address
3, Decorator
An inappropriate analogy. If the method is compared to a photo, the decorator is the photo frame outside the photo. If a beam of light wants to pass through the photo, it must first pass through the front of the photo frame, then through the photo, and finally through the back of the photo frame. The processing we want can be inserted in the gap between the photo frame and the photo
For example, I want to execute a method and calculate the execution time of the method
import time import datetime def test(): start_time = datetime.datetime.now() ''' you code here ''' end_time = datetime.datetime.now() print('Method execution time:'+str(end_time-start_time)) test() # output # Method execution time: 0:00:00.000006
There is no problem with the method itself, but the purpose of writing a method is to simplify the code and improve the reuse rate. Start is defined in each method_ Time and end_time is too cumbersome
1. Decoration method - decorator
Direct code
import time import datetime def count_time(func): def inner(*args, **kwargs): start_time = datetime.datetime.now() res = func(*args, **kwargs) end_time = datetime.datetime.now() print('Method execution time:'+str(end_time-start_time)) return res return inner @ count_time def test(s=1): time.sleep(5) return s re = test(3) print(re) # results of enforcement # Method execution time: 0:00:05.000924 # 3
2. Parameters of decorator
import time import datetime def count_time(text): def wraper(func): def inner(*args, **kwargs): print(text) start_time = datetime.datetime.now() res = func(*args, **kwargs) end_time = datetime.datetime.now() print('Method execution time:'+str(end_time-start_time)) return res return inner return wraper @ count_time('hello') def test(s=1): time.sleep(5) return s re = test(3) print(re) # Operation results # hello # Method execution time: 0:00:05.00000 2 # 3
3. Class method decorator - call self parameter
import time import datetime class Test: def __init__(self, text): self.text = text def count_time(text): def wraper(func): def inner(self, *args, **kwargs): print(text) print(self.text) start_time = datetime.datetime.now() res = func(self, *args, **kwargs) end_time = datetime.datetime.now() print('Method execution time:'+str(end_time-start_time)) return res return inner return wraper @count_time('hello') def a(self): time.sleep(5) a = Test(text='welcome') a.a() # Operation results # hello # welcome # Method execution time: 0:00:05.000297
The advantage of this method is that the parameters of the class can be invoked in the decorator.
It should be noted that in the class decorator, the decorator must be written before the decorated method
Please correct any errors