Tips:新旧クラス対決?《第2版》
Python には(歴史的な経緯から)新旧2つのクラス体系が存在します。
def ex(x):
print "type(x) == x.__class__:",type(x)==x.__class__
print "type(x):",type(x)
print "x.__class__:",x.__class__
組み込み関数 type を利用すると、引数の(指定したインスタンスを規定する)型が得られます。また、属性 __class__ を参照すると、引数の(指定したインスタンスが属する)クラスが得られます。
class Polish: pass >>> x = Polish(); ex() type(x) == x.__class__: False type(x):x.__class__: __main__.Polish
旧クラス体系(old-style classes)では「型とクラス」の間に整合性がありません。すると「異なる」結果が得られるので、False になります。
class Polish(object): pass >>> x = Polish(); ex() type(x) == x.__class__: True type(x):x.__class__:
新クラス体系(new-style classes)では「型とクラス」の間で整合性が保証されています。すると「同じ」結果が得られるので、True になります。
新クラス体系(Python 2.2 以降)では「統一されたフレームワーク」に沿って、洗練されたコードを記述できます。これによって、OOP 言語としての脆弱さが指摘されてきた「組み込み型とクラスとが共存(競合)する状況」での旧体系の問題点を克服できるようになります。
すると、前述した(Python 1.X の時代に作成した)事例も、新クラス体系では、
def ex1(): Polish("3+4") >>> ex1() Traceback (most recent call last): ... File "", line 1, in ex1 def ex1(): Polish("3+4") TypeError: default __new__ takes no parameters
例外 TypeError に伴うエラーメッセージの内容も、少し異なります。
参考文献
- Python Documentation, Release 2.2.3, 30 May 2003
- PEPs 253 and 253: Type and Class Changes