3

x.__class__Pythonインタープリターでは、との値type(x)は同等であると常に信じていました。しかし、次のことを行うと(Python 2.7、3.3、およびPyPy 2.0b1でも):

>>> import weakref
>>> x = set()
>>> y = weakref.proxy(x)
>>> x.__class__, isinstance(x, set), type(x)
(<type 'set'>, True, <type 'set'>)
>>> y.__class__, isinstance(y, set), type(y)
(<type 'set'>, True, <type 'weakproxy'>)

y.__class__のラップされたタイプに対応していることがわかりますweakref.proxy(これはweakref.proxy、変装の属性を置き換えるだけだと思います)。としてもisinstance識別ysetます。

しかしtype、「真の」タイプを示しています- weakproxy。それで、引数の型を識別するために属性をtype使用しませんか?__class__この目的のために「より信頼性の高い」ソースを使用していますか?もしそうなら、私たちはそれに直接アクセスできますか?

4

1 に答える 1

4

x.__class__type(x)同等ではありません。 typeobject.ctype(x)をルートとし、 TrueTypeを返します。ob_type

/ *特殊なケース:type(x)はx->ob_typeを返す必要があります*/

一方x.__class__は単なる属性ルックアップです。object.__getattribute__(x, '__class__')属性ルックアップが再定義されていない限り、これはと同等です。
object's'__class__'はデータ記述子であり、typeobject.cでも定義されています。そのゲッターも戻りますob_type。したがって、ほとんどの場合、同じものx.__class__type(x)返します。

しかしweakproxy、つまり_PyWeakref_ProxyType、意図的に独自に定義しましたproxy_getattr。そのため、あなたの場合y.__class__と同じではありません。type(y)

次の実験でも同じ効果が得られます。

class A(object):
    pass

class C(object):
    def __getattribute__(self, name):
        if name == '__class__':
            return A
        return object.__getattribute__(self, name)


>>> c = C()
>>> c.__class__
<class '__main__.A'>
>>> type(c)
<class '__main__.C'>

さらに、この例では、isinstance(c, A)isinstance(c, C)の両方が当てはまります。isinstance最初の同等性をチェックするのでob_type

于 2013-03-25T22:54:57.113 に答える