
pythonの特殊メソッドの呼ばれ方についての質問です。
例えば、
x + y
を実行した時、
x.__add__(y)
の特殊メソッドが呼ばれると思うのですが、
xの__add__をオーバーロードしてなくて、
yの__radd__をオーバーロードしている場合、
後のオーバーロードした+演算子で解釈される様なのですが、
通常の+の演算子で解釈されるのは、両方の変数(オビジェクト)ともにオーバーロードされていない時という理解でいいのでしょうか?
左辺がオーバーロードされてない時、通常の+演算子、
x.__add__(y)を読み出した時点で、yが通常の変数では無いので、この時点でエラーになる様な気もするので質問しています。
どの様に理解するのがいいのでしょうか?
No.4ベストアンサー
- 回答日時:
> 1.__class__
> や
> 1.__add__(2)
> はSyntaxErrorになる様ですが、何が悪いのでしょうか?
浮動小数点数リテラル ( 1.5 とか)の書式の方が優先され、. が小数点と解釈されています。
そのため、続く文字が「浮動小数点数リテラルとしては不正な文字」なためSyntaxError(文法間違い)になります。
(1).__class__
等と括弧でくくるとか、変数と束縛するとかすれば、属性へのアクセスと解釈されます。
> +の後の方のオブジェクトをオーバーロードした時、
> 1 + オーバーロードしたオブジェクト
> とすると、
> 左辺の1の通常の__add__()が呼び出されてエラーになる様な気がするのですが、
https://docs.python.org/ja/3/reference/datamodel …
https://qiita.com/tell-k/items/ec64a82e7883cb00a …
演算子 + は単純な __add__ / __radd__ メソッドへの置き換えではありません。
a + b で __radd__ が呼ばれるのは次のときです。
・a.__add__ メソッドの無い
・a.__add__(b) メソッドが NotImplemented を返した
・b が aのサブクラス、かつ b.__radd__ が定義されている
1 + オーバーロードしたオブジェクト
↓
(1).__add__(オーバーロードしたオブジェクト)
→ NotImplemented
↓
オーバーロードしたオブジェクト.__radd__(1)
という動作をしています。
>>> class cc:
...□def __radd__(self,x):
...□□print("__radd__ -> 5")
...□□return 5
...
>>> c=cc()
>>> c.__class__
<class '__main__.cc'>
>>> dir(c)
[(略), '__radd__',(略)]
>>> 1 + c
__radd__ -> 5
5
>>> (1).__add__(c)
NotImplemented
No.3
- 回答日時:
> 1 + 2
> は、
> 1のint型には、__add__メソッドは実装されていない、
> 2のint型には、__radd__メソッドは実装されていない
確認しましたか?
>>> a=1
>>> a.__class__
<type 'int'>
>>> dir(a)
['__abs__', '__add__', (略) , '__radd__', (略) ]
>>> a.__add__(2)
3
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.netでメソッドからコントロ...
-
サーブレットコンテキストの意...
-
servletからjspへオブジェクト...
-
エクセルVBA 画像を貼り付ける...
-
Excel VBA 定数にオブジェクト...
-
VBAでの[]
-
PrintFormを使用してのプリント
-
C#で親にイベントを投げる方法
-
Vba ListViewの行挿入に関して...
-
エクセルVBA/SpecialCellsで特...
-
オブジェクトの参照渡しについて
-
エクセルVBAで、条件に一致する...
-
「タイプ初期化子が例外をスロ...
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
文字列を日付に変換でParseExce...
-
EclipseでJSPのコンパイルエラー
-
レコード件数の表示
-
dllと同じプロジェクトにする方法
-
共通で使う関数を集めたクラス...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
servletからjspへオブジェクト...
-
サーブレットコンテキストの意...
-
エクセルVBA 画像を貼り付ける...
-
Excel VBA 定数にオブジェクト...
-
VB.netでメソッドからコントロ...
-
VBAでの[]
-
System.Collections.SortedList
-
JSPでのArrayListの表示につい...
-
C#で親にイベントを投げる方法
-
C#のクラスで値渡しをする
-
VB.NETでのnothing の意義について
-
Vba ListViewの行挿入に関して...
-
String型からlong型への変換は...
-
javaで、、、
-
MessageBox.Show(Me,…の「Me」...
-
getParameter()について
-
ピクチャーボックスに点を打つ...
-
VB2005でADDとINSERTの違いは?
-
singletonクラスとは???
-
LiveConnectって?
おすすめ情報
1 + 2
は、
1のint型には、__add__メソッドは実装されていない、
2のint型には、__radd__メソッドは実装されていない
のに何故、TypeErrorにならないのですか?
ちょっと教えてください。
dir(1)
とすると、同じ様に、
['__abs__', '__add__', (略) , '__radd__', (略) ]
と表示されますが、
1.__class__
や
1.__add__(2)
はSyntaxErrorになる様ですが、何が悪いのでしょうか?
また、
+の後の方のオブジェクトをオーバーロードした時、
1 + オーバーロードしたオブジェクト
とすると、
左辺の1の通常の__add__()が呼び出されてエラーになる様な気がするのですが、
実際には、オーバーロードオブジェクトの__radd__()が呼ばれて上手くいく様なのですが、
オーバーロードしたオブジェクトがあれば、そちらが優先されるみたいなルールってあるのですか?