下記のように組み込みデータ型の親クラスは、objectになります。
python
1>>> for i in int, float, str: 2... print(i.__bases__) 3... 4(<class 'object'>,) 5(<class 'object'>,) 6(<class 'object'>,)
objectクラス内を覗いてみると__float__
はありません。
python
1>>> dir(float.__bases__) 2['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index'] 3>>>
そのため、objectクラスの__float__()
にアクセスしようとすると、当然ないのでアクセスできません。
python
1>>> class Test: 2... def base_class(self): 3... print(super().__float__) 4... print(super()) 5... print(dir(super())) 6... return "OK" 7... 8>>> t1 = Test() 9>>> t1 10<__main__.Test object at 0x107e0abe0> 11>>> t1.base_class() 12Traceback (most recent call last): 13 File "<stdin>", line 1, in <module> 14 File "<stdin>", line 3, in base_class 15AttributeError: 'super' object has no attribute '__float__'
一方で、floatを継承して親クラスを確認してみると、floatクラスではなく、objectクラスが親クラスになっているようにもみえます。そして、objectクラスの__float__()
を呼び出しているようにみえます。
floatクラスを明示的に継承してるはずなのに、なぜprint(super())の結果にfloatクラスが含まれていないのか理解できないので、ご存知のかた教えていただけませんでしょうか?
python
1>>> class Test2(float): 2... def base_class(self): 3... print(super().__float__()) 4... print(super()) 5... print(dir(super())) 6... return "OK" 7... 8>>> t2 = Test2() 9>>> t2 100.0 11>>> t2.base_class() 120.0 13<super: <class 'Test2'>, <Test2 object>> 14['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__self_class__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__thisclass__'] 15'OK'
しかし、__bases__
で確認すると親クラスは、floatになっていますが、__float__
は存在しません。
だとすると、上記のコードでsuper().__float__()
で__float__()
にアクセスできている理由の意味が全くわかりません。
また、上記のコードでは、継承されていないようにみえたのに__bases__
だと継承されてることがわかるのが理解できません。
python
1>>> Test2.__bases__ 2(<class 'float'>,) 3>>> dir(Test2.__bases__) 4['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
以上から、組み込み型のfloatは、クラスなので下記のようにbuiltin scope内で定義されているだろうという仮説がたちますが、実際には、どうやらそういった実装にはなっていないようにみえます。
python
1class object: 2 def __init__(): 3 ... 4 5class float(object): 6 ... 7 def __float__(): 8 ...
では、改めてfloatの親クラスをみてみますが、objectになっています。さて、このobjectは、何者なんでしょうか?floatとなんの関係があるのでしょうか? __float__()
は、一体どこのクラス内に定義されたスペシャルメソッド、スペシャル属性なのでしょうか?
python
1>>> float.__bases__ 2(<class 'object'>,)
回答3件
あなたの回答
tips
プレビュー