オブジェクトからクラスオブジェクトを得る

特殊メソッドである__class__からクラスオブジェクトを得ることができます。

class Foo():
    pass

foo = Foo()

print(Foo)
print(foo.__class__)
$ py main.py
<class '__main__.Foo'>
<class '__main__.Foo'>

取れてますね。


使い道としては例えば以下のような自分自身を生成するようなメソッドを提供する場合

class Foo():
    def clone(self):
        return Foo()

class Bar(Foo):
    pass

foo = Foo()
bar = Bar()
print(foo.clone())
print(bar.clone())
$ py main.py
<__main__.Foo object at 0x000000000220A908>
<__main__.Foo object at 0x000000000220A908>

このように「return Foo()」でクラス名を固定して返すと継承したときにBar.cloneがFooのオブジェクトを返してしまいます。

ここでBarを返したい場合、__class__を使うと実現できます。

class Foo():
    def clone(self):
        return self.__class__()

class Bar(Foo):
    pass

foo = Foo()
bar = Bar()
print(foo.clone())
print(bar.clone())
$ py main.py
<__main__.Foo object at 0x000000000225A908>
<__main__.Bar object at 0x000000000225A908>

うまくいってますね。