解惑(一) ----- super(XXX, self).__init__()到底是代表什么含义
好文不應該被埋沒,然后我重新潤色的一下,應該被更多的人所熟知!!!
轉載:https://blog.csdn.net/zyh19980527/article/details/107206483/
相信大家在很多場合特別是寫神經網絡的代碼的時候都看到過下面的這種代碼:
import torch import torch.nn as nn import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()# 輸入圖像channel:1;輸出channel:6;5x5卷積核self.conv1 = nn.Conv2d(1, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)# an affine operation: y = Wx + bself.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 poolingx = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# 如果是方陣,則可以只使用一個數字進行定義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大家可能剛開始會有點疑惑的是下面的這三行代碼是干什么用的,要看懂這三行代碼需要了解三個東西:
- self參數
- __ init__ ()方法
- super(Net, self).init()
接下來就為大家逐一講解一下。
一、self參數
self指的是實例Instance本身,在Python類中規定,函數的第一個參數是實例對象本身,并且約定俗成,把其名字寫為self,也就是說,類中的方法的第一個參數一定要是self,而且不能省略。
我覺得關于self有三點是很重要的:
- self指的是實例本身,而不是類
- self可以用this替代,但是不要這么去寫
- 類的方法中的self不可以省略
首先第一點self指的是實例本身,而不是類
class Person():def eat(self):print(self)Bob=Person() Bob.eat() print(Person)
看輸出的結果我們可以看到,self指的是實例對象,并不是一個類
第二點self可以用this替代,但是不要這么去寫,其實我理解self就相當于Java中的this,我們試著換一下
class Person():def eat(this):print(this)Bob=Person() Bob.eat() print(Person)
是沒有報錯的,但是大家還是按照規范用self
第三點類的方法中的self不可以省略,看下面的代碼,pycharm自動提示需要參數self。
二、__ init__ ()方法
在python中創建類后,通常會創建一個\ __ init__ ()方法,這個方法會在創建類的實例的時候自動執行。 \ __ init__ ()方法必須包含一個self參數,而且要是第一個參數。
比如下面例子中的代碼,我們在實例化Bob這個對象的時候,\ __ init__ ()方法就已經自動執行了,但是如果不是\ __ init__ ()方法,比如說eat()方法,那肯定就只有調用才執行
class Person():def __init__(self):print("是一個人")def eat(self):print("要吃飯" ) Bob=Person()再比如說下面的代碼,如果 \ __ init__ ()方法中還需要傳入另一個參數name,但是我們在創建Bob的實例的時候沒有傳入name,那么程序就會報錯, 說我們少了一個\ __ init__ ()方法的參數,因為\ __ init__ ()方法是會在創建實例的過程中自動執行的,這個時候發現沒有name參數,肯定就報錯了!
class Person():def __init__(self,name):print("是一個人")self.name=namedef eat(self):print("%s要吃飯" %self.name)Bob=Person() Bob.eat()
傳入了Bob之后就不會了,而且eat方法也可以使用name這個參數。
這樣我們其實就比較清晰的知道什么東西需要在\ __ init__ ()方法中定義了,就是希望有一些操作是在創建實例的時候就有的時候,比如說下面的這個代碼,其實就應該把money這個量定義在\ __ init__ ()方法中,這樣就不需要在執行eat()方法后再執行qian()方法。或者說我們寫神經網絡的代碼的時候,一些網絡結構的設置,也最好放在\ __ init__ ()方法中。
三、super(Net, self).__init__()
Python中的super(Net, self).__init__()是指首先找到Net的父類(比如是類NNet),然后把類Net的對象self轉換為類NNet的對象,然后“被轉換”的類NNet對象調用自己的init函數,其實簡單理解就是子類把父類的__init__()放到自己的__init__()當中,這樣子類就有了父類的__init__()的那些東西。
回過頭來看看我們的我們最上面的代碼,Net類繼承nn.Module,super(Net, self).__init__()就是對繼承自父類nn.Module的屬性進行初始化。而且是用nn.Module的初始化方法來初始化繼承的屬性。
class Net(nn.Module):def __init__(self):super(Net, self).__init__()# 輸入圖像channel:1;輸出channel:6;5x5卷積核self.conv1 = nn.Conv2d(1, 6, 5)也就是說,子類繼承了父類的所有屬性和方法,父類屬性自然會用父類方法來進行初始化。
舉個例子幫助大家理解:
當然,如果初始化的邏輯與父類的不同,不使用父類的方法,自己重新初始化也是可以的。比如:
class Person(object):def __init__(self,name,gender,age):self.name = nameself.gender = genderself.age = ageclass Student(Person):def __init__(self,name,gender,age,school,score):#super(Student,self).__init__(name,gender,age)self.name = name.upper() self.gender = gender.upper()self.school = schoolself.score = scores = Student('Alice','female',18,'Middle school',87) print s.school print s.name總結
以上是生活随笔為你收集整理的解惑(一) ----- super(XXX, self).__init__()到底是代表什么含义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动数字广告与互联网反欺诈蓝皮报告
- 下一篇: 互联网晚报 | 12月31日 星期五 |