Python Basics - Super (XXX, self)__ init__ () learning and understanding

On many occasions, especially when writing neural network code, I often see the following code examples:

Definition of neural network under TensorFlow framework:

class BertIntentModel(object):
	def __init__(self):
		super(BertIntentModel, self).__init__()
		self.dict_path = '/Users/vocab.txt'
		self.config_path = '/Users/bert_config_rbt3.json'
		self.checkpoint_path = '/Users/bert_model.ckpt'

		self.label_list = [line.strip() for line in open('label','r',encoding='utf8')]
		self.id2label = {idx:label for idx,label in enumerate(self.label_list)}

		self.tokenizer = Tokenizer(self.dict_path)
		self.model = build_bert_model(self.config_path, self.checkpoint_path, 13)
		# self.model.load_weights('./checkpoint/best_model.weights')   # By default, the specified file under the peer folder is called
		self.model.load_weights('/Users/checkpoint/best_model.weights')

Definition of neural network under PyTorch framework:

import torch
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # Input image channel: 1; Output channel: 6; 5x5 convolution kernel
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # an affine operation: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 2x2 Max pooling
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # If it is a square matrix, it can be defined with only one number
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

The code line is super (BERT intent model, self)__ init__ () function description:

1. self parameter - Introduction

Self refers to the Instance itself. It is stipulated in the Python class that the first parameter of the function is the Instance object itself, and it is customary to write its name as self, that is, the first parameter of the method in the class must be self and cannot be omitted.

There are three important points about self:

  • self refers to the instance itself, not the class;
  • self can be replaced by other variables, such as this, but it is generally not written in this way;
  • self in the method of class cannot be omitted.

Example 1:

The following example proves that [self refers to the instance itself, not the class]

# self refers to the instance itself, not the class;
class Person():
    def eat(self):
        print(self)
        
Bob = Person()
Bob.eat()
print(Person)

>>>
<__main__.Person object at 0x7fc63d3ba9d0>
<class '__main__.Person'>

Looking at the output, we can see that self refers to an instance object, not a class

Example 2:

The following example proves that [self can be replaced by other variables, such as this, but it is generally not written in this way]. Let's try to change it:

class Person():
    def eat(this):
        print(this)
        
Bob = Person()
Bob.eat()
print(Person)

>>>
<__main__.Person object at 0x7fc63c967520>
<class '__main__.Person'>

Looking at the output results, we can see that there is no error, but it is recommended to use self according to the specification.

Example 3:

The following example proves that [self in class methods cannot be omitted]. See the following code:

class Person():
    def eat():
        print(self)
        
Bob = Person()
Bob.eat()
print(Person)

>>>
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/var/folders/39/ltj3xcv91_1dqzzsgmwy0s980000gn/T/ipykernel_83456/2411217618.py in <module>
      4 
      5 Bob = Person()
----> 6 Bob.eat()
      7 print(Person)

TypeError: eat() takes 0 positional arguments but 1 was given

2. __ init__ () method - Introduction

After you create a class in python, you usually create one__ init__ () method, which will be executed automatically when creating an instance of the class.

  • __ init__ () method must contain a self parameter, and if it is the first parameter.

Instance 1 - [when instantiating Bob, the _ init _ () method will execute automatically]:

In the following example, when we instantiate Bob__ init__ () method has been executed automatically. If not__ init__ () method, such as eat() method, will be executed only when called.

class Person():
    def __init__(self):
        print("It's a person")
    def eat(self):
        print("Want to eat")
        
Bob = Person()

>>>
It's a person

Instance 2 - [if another parameter needs to be passed in the _ init method, but this parameter is not passed in when creating an instance of Bob, the program will report an error]:

In the following example, if__ init__ Another parameter name needs to be passed in the () method, but when we create an instance of Bob, we do not pass in name. Then the program will report an error, saying that we are missing one__ init__ () method because__ init__ The () method will be automatically executed during the instance creation process. If it is found that there is no name parameter at this time, an error will be reported.

class Person():
    def __init__(self, name):
        print("It's a person")
        self.name = name
    def eat(self):
        print("%s Want to eat" %self.name)
        
Bob = Person()  #Error call
# Bob = Person("Bob")   #Call correctly
Bob.eat()  
print(Person)
>>>
It's a person
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/var/folders/39/ltj3xcv91_1dqzzsgmwy0s980000gn/T/ipykernel_83456/4210195990.py in <module>
      6         print("%s Want to eat" %self.name)
      7 
----> 8 Bob = Person()
      9 Bob.eat()
     10 print(Person)

TypeError: __init__() missing 1 required positional argument: 'name'

Not after Bob is passed in, and the eat method can also use the name parameter.

What needs to be put in__ init__ () which methods do not need???

  • Need in__ init__ () method: some operations are expected to be automatically created when creating an instance.
  • Need in__ init__ () definition in method: in the neural network code, some network structure settings should also be placed in__ init__ () method.

In the following code, the amount of money should be defined in__ init__ () method, so there is no need to execute the qian() method after executing the eat() method.

class Person():
    def __init__(self, name):
        print("It's a person")
        self.name = name
    def eat(self,money):
        print("%s Want to eat" %self.name)
        self.money = money
    def qian(self):
        print("Spent%s element" %self.money)
        
Bob = Person("Bob")
Bob.eat(12)
Bob.qian()

>>>
It's a person
Bob Want to eat
 It cost 12 yuan

3. super(Net, self).init() -- initializes the attributes inherited from the parent class, and initializes the inherited attributes with the initialization method of the parent class

In fact, a parent class is more like a child function of a child class. This sentence may be awkward. In short, it is the code line super (net, self) in the child class__ init__ () implementation calls the parent class.

Specific process: Super (Net, self) in Python__ init__ () refers to first finding the parent class of Net (such as class NNet), then converting the Net like object self into an NNet like object, and then the "converted" NNet like object calls its own init function. In fact, the simple understanding is that the subclass puts the _init_ () of the parent class into its own__ init__ (), so the subclass inherits the parent class__ init__ () those things. In other words, the subclass inherits all the properties and methods of the parent class, and the parent class properties will naturally be initialized with the parent class method. Of course, if the initialization logic is different from that of the parent class, you can reinitialize yourself without using the methods of the parent class.

In the following code block, the subclass Net class inherits the parent class NN Module, super (Net, self) in the function body__ init__ () is inherited from the parent class NN Module. And it's NN Module to initialize inherited properties.

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # Input image channel: 1; Output channel: 6; 5x5 convolution kernel
        self.conv1 = nn.Conv2d(1, 6, 5)

In other words, the subclass inherits all the properties and methods of the parent class, and the parent class properties will naturally be initialized with the parent class method.

Take an example to help you understand:

class Person():
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
    def printinfo(self):
        print(self.name, self.gender)
        
class Stu(Person):
    def __init__(self, name, gender, school):
        super(Stu, self).__init__(name, gender)  # Use the initialization method of the parent class to initialize the child class
        self.school = school
    def printinfo(self):   # Override the printinfo method of the parent class
        print(self.name, self.gender, self.school) 
    
if __name__=='__main__':
    stu = Stu('Bob', 'female', '5th')
    stu.printinfo()
>>>
Bob female 5th

Of course, if the initialization logic is different from that of the parent class, you can reinitialize yourself without using the methods of the parent class. For example:

class Person(object):
    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age
class Student(Person):
    def __init__(self, name, gender, age, school, score):
        super(Student, self).__init__(name,gender, age)
        self.name = name.upper()  # Change to uppercase
        self.gender = gender.upper()  # Change to uppercase
        self.school = school
        self.score = score
        
s = Student("Alice", "female", "18", "High school", "17")
print(s.name, s.gender, s.school, s.score)

>>>
ALICE FEMALE High school 17

Reference link: Puzzle solving (I) -- Super (XXX, self) What exactly does init () mean

Keywords: Python Pytorch Deep Learning

Added by homchz on Tue, 04 Jan 2022 03:44:57 +0200