1. __coerce__ と __getattr__
- Python 2 ではオブジェクト本体が参照された時にも __getattr__(self, x) メソッドが呼ばれる。x には、通常 文字列 '__repr__' が代入されるが、異なる方との算術演算として呼び出された時には文字列 '__coerce__' が代入される。
- Python 2 には型強制 coercion があったが Python 3 ではなくなった。
original = 42
class FooProxy:
def __getattr__(self, x):
print(x, type(x))
return getattr(original, x)
proxy = FooProxy()
proxy
1 + proxy
proxy + 1
>>> # Python 2.7
>>> proxy
('__repr__', <type 'str'>)
42
>>>
>>> 1 + proxy
('__coerce__', <type 'str'>)
43
>>>
>>> proxy + 1
('__coerce__', <type 'str'>)
43
>>>
>>> # Python 3
>>> proxy
<__main__.FooProxy object at 0x109c854e0>
>>>
>>> 1 + proxy
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'FooProxy'
>>>
>>> proxy + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'FooProxy' and 'int'
>>>
object.__coerce__
"型混合モード (mixed-mode)" での数値間の算術演算を実現するために呼び出されます。 self と other を共通の数値型に変換して、 2 要素のタプルにして返すか、不可能な場合には None を返さなければなりません。共通の型が other の型になる場合、 None を返すだけで十分です。この場合、インタプリタはもう一方のオブジェクトを調べて型強制を行おうとするからです (とはいえ、もう一方の値の型が実装上変更できない場合には、ここで self を other の型に変換しておいた方が便利です)。戻り値に NotImplemented を使うのは、 None を返すのと同じです。
3.4.9. 型強制規則 (coercion rule)
本節では、型強制 (coercion) に関する規則について記述します。プログラム言語が進化するにつれ、型強制規則について正確に記述するのは難しくなってゆきます; 従って、あるバージョンのある実装について記述するのは望ましくありません。その代わりに、型強制に関する非公式的なガイドラインを示しておきます。 Python 3 からは、型強制がサポートされなくなる予定です。
2. __repr__
- Python 2 では 組込型では type, ユーザ定義型では class と表示されるのに対して
- Python 3 では 組込型でも class, ユーザ定義型でも class と表示されるようになった。
class C:
pass
C
int
>>> # Python 2
>>> C
<class __main__.C at 0x10ad70a78>
>>> int
<type 'int'>
>>>
>>> # Python 3
>>> C
<class '__main__.C'>
>>> int
<class 'int'>
>>>