self.__class__最初に、変更中の回答に基づいた回答を提供しました__init__()。これは避けるべきだとコメントで説明されました。
今、私は基本クラスの再定義に基づいた答えを提供しています__new__。
class Car(object):
"""The base class."""
def __new__(cls, max_speed):
if cls is Car and max_speed > 100:
return object.__new__(SuperCar, max_speed)
else:
return object.__new__(cls, max_speed)
def __init__(self, max_speed):
self.max_speed = max_speed
class SuperCar(Car):
"""The sub class."""
pass
インスタンスの作成を担当するコードは、組み込みの in(1)__new__メソッドにあります。クラスが呼び出されたときに呼び出され (例: my_car = Car(100))、その呼び出しで指定された引数が渡されます。
aCarまたは aのインスタンスSuperCar化 ( の継承による__new__) が呼び出されると、再定義された は、作成されるインスタンスが であり、かつが 100 より大きい__new__かどうかをチェックします。cls Carmax_speed
SuperCarその場合、 の代わりに のインスタンスを作成し、それをCar返しobject.__new__(SuperCar, max_speed)ます。
__new__それ以外の場合は、このインスタンスを作成するために組み込みの通常のデフォルトを呼び出し、それを使用object.__new__(cls, max_speed)して返します。not max_speed > 100これは、予想されるケースと、この再定義__new__がサブクラスによって呼び出されるケースSuperCar(のように)をキャッチしmy_ferrari = SuperCar(250)ます。
記録のために、これが私の以前の答えです:
インスタンスの作成時に、ある条件に応じてインスタンスのクラスをそのサブクラスの 1 つに変更する場合は、次の__init__ように でいくつかのロジックを使用できます。
class Car(object):
def __init__(self, max_speed_kph):
if self.__class__ == Car:
if max_speed_kph > 230:
self.__class__ = SuperCar
self.__init__()
class SuperCar(Car):
def __init__(self):
print 'this car is fast!'
これself.__init__()は、新しいクラスとしてインスタンスを再初期化するためのものです。
脚注:
- これは本当にビルトインですか?Python ドキュメントの「組み込み関数」トピックには表示されません。