くないらぼ

python でおかねをあならいず

プリミティブ型( というか Built-in Types ? )を継承して、自前クラスを作る

プリミティブ型*1 ( というか Built-in Types ? )を継承して、自前クラスを作る

今までポジションの管理をするクラスを作る時などには、メンバー変数にlistを持ったクラスを作っていました。 ふと、包含じゃなくてlistを継承すれば良くね?と気づいたので試してみました。

結論としては、特に気にせず普通に継承すれば問題無いです。(そりゃそうだ)


# list型を単純に拡張する
class MyList(list):
    def my_method(self):
        for i in self:
            print(i)

l = MyList()
l.append(3)
l.my_method() # 3
l.append("eee")
l.my_method() # 3 eee

 

ここで、listのIFを保ちたいために、同名メソッドのappendをオーバーライドしたい場合、 superにて親クラスのメソッドだという明示が必要です。

# 既にあるlistのappendを使いつつ継承する(=フックする)には、superで呼ぶ。
class MyListHooked(list):
    def append(self, aaa):
        print("hooked!")
        super(MyListHooked, self).append( aaa )

h = MyListHooked()
h.append("aaa") # hooked!
h # ['aaa']

 

listならlenはよく使いますし、lenも使えるようにしますか。

# まあまあ使いそうな、len のオーバーロード
class AA(list):
    def __len__(self):
        print("hooked, len is ...")
        return super(AA, self).__len__()

A = AA()
print("len: ", len(A)) # 0
A.append(3)
print("len: ", len(A)) # 1

意外にプリミティブな型で継承をやったこと無かったので新鮮な気持ちになったのでメモってみました。 ただ、for文でselfをイテレーションするのには違和感がありますねw (list や dict のようにイテレーション用の専用メソッドが実装してある時のみ可能)

べんりなのに、なんか違和感があるのがとても面白かったです。(小学生)

*1:プリミティブ型 と書いたのですが、pythonは全てObject型を継承しているので、厳密にはプリミティブな型はありません。ここでは list, float, strなどのデフォルトの型を指す用語としてプリミティブ型を使います。