Frage

Was ist der Unterschied zwischen type(obj) und obj.__class__? Gibt es überhaupt eine Möglichkeit type(obj) is not obj.__class__?

Ich möchte eine Funktion schreiben, die allgemein auf den gelieferten Objekten arbeitet, einen Standardwert von 1 in der gleichen Art wie ein anderer Parameter verwendet wird. Welche Variante # 1 oder # 2 unten gehen, das Richtige zu tun?

def f(a, b=None):
  if b is None:
    b = type(a)(1) # #1
    b = a.__class__(1) # #2
War es hilfreich?

Lösung

type(obj) und type.__class__ verhalten sich nicht gleich für alten Stil Klassen:

>>> class a(object):
...     pass
...
>>> class b(a):
...     pass
...
>>> class c:
...     pass
...
>>> ai=a()
>>> bi=b()
>>> ci=c()
>>> type(ai) is ai.__class__
True
>>> type(bi) is bi.__class__
True
>>> type(ci) is ci.__class__
False

Andere Tipps

Dies ist eine alte Frage, aber keine der Antworten scheint, dass zu erwähnen. im allgemeinen Fall, es möglich, dass eine neuen Stil-Klasse unterschiedliche Werte für type(instance) und instance.__class__ muß:

class ClassA(object):
    def display(self):
        print("ClassA")

class ClassB(object):
    __class__ = ClassA

    def display(self):
        print("ClassB")

instance = ClassB()

print(type(instance))
print(instance.__class__)
instance.display()

Ausgabe:

<class '__main__.ClassB'>
<class '__main__.ClassA'>
ClassB

Der Grund dafür ist, dass ClassB den __class__ Descriptor überschreiben, aber das interne Typenfeld in dem Objekt wird nicht verändert. type(instance) liest unmittelbar von diesem Typ-Feld, so gibt sie den korrekten Wert, während instance.__class__ auf den neuen Deskriptor bezieht sich den ursprünglichen Deskriptor durch Python vorgesehen ersetzt, die das interne Typfeld liest. Statt dass die interne Feld liest, gibt es einen fest codierten Wert.

Old-Style-Klassen sind das Problem, Seufzer:

>>> class old: pass
... 
>>> x=old()
>>> type(x)
<type 'instance'>
>>> x.__class__
<class __main__.old at 0x6a150>
>>> 

Kein Problem in Python 3, da alle Klassen neue Stile sind jetzt; -).

In Python 2, eine Klasse ist neu Stil nur, wenn es von einer anderen neuen Stil-Klasse erbt (einschließlich object und der verschiedenen eingebauten Typen wie dict, list, set, ...) oder implizit oder explizit setzt __metaclass__ type.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top