3

特にPython3で削除されるため、古いスタイルのPythonクラスは推奨されなくなりました。ただし、ここで何が起こっているのかを理解したいと思います。

class MyClass:
  pass

my_instance = MyClass()
str(my_instance)

このスニペットは以下を出力します。

'< 0x108ec4290のメイン.MyClassインスタンス>'

したがって、明示的な継承はなく、 strメソッドをオーバーロードしませんでした。ただし、これはおそらく欠落しているメソッドの例外を発生させません。なんで?

古いスタイルのクラスには「インスタンス」と「タイプ」の概念があり、新しいスタイルのクラスはこれらの概念を統合することを目的としていることを私は知っています。では、Pythonは、インスタンスが暗黙的に接続されている「インスタンス」タイプのstrメソッドを見つけて呼び出していますか?

ここにいくつかの手がかりがあります:

dir(my_instance)-戻り値:

['__doc__', '__module__']

type(my_instance)-戻り値:

<type 'instance'>

dir(type(my_instance))-戻り値:

['__abs__', '__add__', '__and__', '__call__', '__class__', '__cmp__', '__coerce__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__div__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__', '__idiv__', '__ifloordiv__', '__ilshift__', '__imod__', '__imul__', '__index__', '__init__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'next']

古いスタイルのクラスのクラスとタイプの関係と、ここで何が起こっているのかを正確に説明できる人はいますか?

4

1 に答える 1

1

他の人がこれについてもっと具体的な理由を教えてくれると思いますが、ここにある同様の議論からの引用があります:古いスタイルのクラス

object継承ツリーの最上位にある基本クラスです。基本クラスを主張する目的は、あまり多くの「魔法」を必要とせずにオブジェクトの動作を統一することだと私は信じています。つまり、新しいスタイルのクラスの前は、オブジェクトは魔法のように__doc__ とのようなプロパティを持っていました__str__。今、彼らは理由のためにそれらを持っています:彼らは基本クラスからそれらを継承したからです。

私が信じる「魔法」についてのその部分はまさにそれです...ブラックボックスの魔法。instance明らかに、古いスタイルのクラスのMRO(メソッド解決順序)は、オブジェクトとの両方の明示的な定義をチェックする必要があるという点で、はるかに魔法のようなものでしたtype。それ、または古いスタイルのクラスの仕組みの一部は、__str__場所が見つからない場合に常にデフォルトのメソッドを提供することです。

新しいスタイルのクラスでは、継承のおかげでメソッドがインスタンス上に実際に存在するため、魔法のようなものではなくなります。

ここにいくつかの良い引用と例がある別のサイトがあります:最大の驚きの原則

古いスタイルのクラスの場合、すべてのルックアップはインスタンスで実行されます。

新しいスタイルのクラスのインスタンスの場合、暗黙的に実行されるすべての特別なメソッドルックアップはクラス構造体で実行されます

新しいスタイル:

class Foo(object):
    def __str__(self):
        return "old str"

foo = Foo()
foo.__str__ = lambda: "new str"

print str(foo)
print foo.__str__()

# old str
# new str

オールドスタイル:

class Foo:
    def __str__(self):
        return "old str"

foo = Foo()
foo.__str__ = lambda: "new str"

print str(foo)
print foo.__str__()

# new str
# new str
于 2012-09-01T00:22:00.013 に答える