pytorchで実装されたコードを見ていると
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
のように、サブクラス化した後にスーパークラスのコンストラクタにサブクラス自身を与えているコードがある。
しかし、このコードってsuper(Model, self).__init__()
じゃなくてsuper().__init__
(self)でも動くんじゃない? なぜsuper().__init__(self)
じゃないの??
って思ってコードを書き換えて使ってみると問題なく動いた。
では、なぜ自身のクラスをスーパークラスのコンストラクタに与えているのだろうと調べてみると、意外とそれらしい記事が見つからないが、頑張ってやっと見つけることができた。
その理由はいたってシンプルで、Pythonのバージョンに対応するためのものだそうだ。
super().__init__(self)
という書き方はPython 3.x
で動作するが、Python 2.x
では動作しないらしい。
Pythonを本格的に触りだしてからは基本的にPython 3.x系だったのでこの辺は全く知らなかったが、おそらくPython 2.x系を使っている人だったら当たり前すぎて誰も記事にしていなかったのだと思う。
Python2.xの場合はサブクラスの定義をするときにはsuper(Model, self).__init__() のように自信を再帰的に定義するのは常識のようだ。
pytorchのフォーラムのトピックに以前はまさにこれに関する投稿があったらしいが、現在はちょっと見つけきれなかった。
普通に”クラス継承 super( child ) “のような検索ワードで検索してもなかなか見つからなかったが、同じようにPython3.x系をメインで使っているからなぜこんな風にやっているのか疑問と思った人に対してのアンサーになれれば幸いです。
以上、torch.nn.Module()のサブクラス化におけるsuper(Model, self).__init__()とsuper().__init__(self)の違いに関してでした。
コメント