2016-05-18 5 views
4

を期待するようrtruedivが動作しない、私が作成します。のPython:私のpythonのV3を使用して

class NewInt(int): 
    def __rtruediv__(self, num): 
    print('in here') 

x = NewInt(5) 

343/x # called rtruediv as I expect, but 

343.3/x # does not call rtruediv 

わからない理由ので、これは次のとおりです、これは矛盾しているようだ私に

x/343 
x/343.3 #both will call truediv 

..

誰かがこれがなぜ..であるのかについての説明を持っています。また、Pythonが343.3/xの場合、オーバーライドできるメソッドがありますか?

オーバーロードに関する情報を確認したときにこの現象が検出され、この不一致が発生しました。

デイブ

答えて

3

__rtruediv__右辺のオペランドが左のオペランドのクラスのサブクラスのインスタンスである場合にのみ__truediv__優先します。あなたが343/xを行うと

は、NewIntintのサブクラスなので、Xの__rtruediv__が優先権を得ます。 343.3/xを実行するとNewIntfloatのサブクラスではないため、343.3の__truediv__が優先されます。

343.3.__truediv__(x)floatはintで浮動小数点を除算する方法を知っています。したがって、x.__rtruediv__は呼び出されません。

3

要するに、いくつかの特殊な状況を除いて、左側のオペランドが操作を処理する際に最初のショットを取得します。ここ

関連文書はemulating numeric typesである:

注:右オペランドの型は、左オペランドの型のサブクラスであり、そのサブクラスが操作に反映する方法を提供している場合、このメソッドは、前に呼び出されます左オペランドの非反映メソッド。この動作により、サブクラスは先祖操作をオーバーライドできます。

程度の場合:

343.3/x # does not call rtruediv 

intによってfloat分割が定義されているので、左側が勝つ、及びis a N intNewInt。つまり、343.3.__truediv__(x)はエラーなしで成功します。

のは、ここに矛盾する行動が実際に存在しないことを確認するためにドキュメントの光の中ですべての4つのケースを調整してみましょう:

343/x  # x.__rtruediv__ wins because NewInt subclasses int 
343.3/x # 343.3.__truediv__ wins because NewInt doesn't subclass float 
x/343  # x.__truediv__ wins because int doesn't subclass NewInt 
x/343.3 # x.__truediv__ wins because float doesn't subclass NewInt 
+0

ああ。これと下図の両方が素晴らしい答えです。私は、Pythonがオペレータの右側のオブジェクトをどのように扱うかについての実際の詳細は知らなかった。それは私が期待していたものではありません。そして今、私はそれがこのようにする必要があることを見ることができます。実際には、343.3/xは、floatオブジェクトのtruedivメソッドを使用しているため、NewIntの新しいメソッドを使用する操作をオーバーライドする方法はありません。オーバーライディングのオペレータは、最初に考えるよりも複雑になります。いくつかのテキストは、この「詳細」を外すようです。 – Dave

+0

これは間違いです。'NewInt'が' int'を継承しないように変更されていれば(または、浮動小数点数による分割方法を知っている他のクラスでも)可能です。この場合、左手側の試行は失敗するが、右手側が今度は打ち上げられる。そして、 '__rtruediv__'を正しく実装したと仮定すると、右のオペランドの除算メソッドの結果はエラーなしで返されます。 – wim

関連する問題