python learning experience: methods, parameters, decorators

Keywords: Python Pycharm crawler

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

Posted by zeh on Sun, 05 Sep 2021 17:48:53 -0700