この記事の要約
- Python内で同じ名前のクラスがあってもエラーなく実行できる
- C++だと同じ名前のクラスがあればコンパイル時にエラーになる
- 特に大した情報を載せている記事ではない(重要)
- このエラー解決に丸1日費やした自分への戒め
Python内で同じ名前のクラスを作って実行してみる
import os
import sys
class CLS:
def __init__(self):
self.value = 1
def print_value(self):
print('value =', self.value)
class CLS:
def __init__(self):
self.value = 2
def print_value(self):
print('value =', self.value)
def main():
cls = CLS()
cls.print_value()
if __name__ == "__main__":
main()
CLSという同じ名前のクラスを宣言しています.最初のCLSではvalueの値を1にし,次のCLSではvalueの値を2としています.これを実行すると
value = 2
2が表示されます.つまり,後から宣言されたCLSに置き換えられたことになります.
C++内で同じ名前のクラスを作ってコンパイルしてみる
同様のことをC++でも行ってみます.
#include <iostream>
class CLS {
private:
int value_;
public:
CLS(void): value_(1) {}
void printValue(void) { printf("value = %d\n", value_); }
};
class CLS {
private:
int value_;
public:
CLS(void): value_(2) {}
void printValue(void) { printf("value = %d\n", value_); }
};
int main(int argc, char **argv) {
CLS cls;
cls.printValue();
return 0;
}
コンパイルしてみます.
$ g++ -o class class.cpp
error: redefinition of ‘class CLS’
コンパイル時にエラーとなります.C/C++に慣れている人であれば当たり前の挙動ですね.当然ですが,それぞれのクラスを異なるnamespace内で宣言すれば,同じ名前のクラスを宣言することはできますし,使い分けることもできます.
なぜこの記事を書いたか
Keras(Tensorflowバックエンド)を使ってLSTMを実装しようとしました.LSTMを実装するクラスの名前を何にしようか迷った時に,安易に「class LSTM」と名付けてしまいました.当然,Kerasの中にもLSTMというクラスが宣言されています.その結果,Keras内で宣言されているLSTMが,自分が実装したLSTMで上書きされました.つまり,
class LSTM:
def __init__(self):
# do something
x = LSTM(32, activation='relu')(x)
みたいなコードを書いてしまい,これを実行して
TypeError: __init__() got an unexpected keyword argument 'activation'
というエラーが出てきたわけです.「LSTMにactivationがないなんておかしい」と思うわけですが,KerasのLSTMは自分で実装したLSTMというクラスに上書きされているので当然です(しかし気づかない...).
そして,「エラーが出たらググる」が基本ですのでググると,KerasとTensorflowのバージョンの問題で「got an unexpected keyword argument」というエラーが出るという記事を見つけました(これもまた運が悪い...).そうなると,「これはバージョンの問題か!」と思って意気揚々とバージョン合わせを行うわけですが,一向にエラーが解決しません.
様々なバージョンを試し結局解決できず,今日は帰ろうかと思い最後にプログラムを眺めている時に,「LSTMって名前被ってるじゃん」と気づきました.そして名前を直したらあっけなく動きました.私はC++をメインに扱っているので,「同じ名前ならエラー出せよ!」と思いましたが,良くも悪くもこれがPythonなのですね.
今日(2020年12月4日)1日をこのエラー解決に全て費やした自分の愚かさを反省する意味も込めて,久しぶりの記事投稿です.同じエラーに苦しむ方の手助けになれば幸いです(そんなやついるか怪しいですが...).