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