2013-03-30 12 views
10

mi sono imbattuto in questa lettura del pitone documentation sulla parola chiave super:Qual è la differenza tra un 'Tipo' e di un 'oggetto' in Python

Se il secondo argomento viene omesso, l'oggetto eccellente restituito è non legato . Se il secondo argomento è un oggetto, isinstance (obj, type) deve essere vero. Se il secondo argomento è un tipo, issubclass (type2, type) deve essere true (questo è utile per classmethods).

Qualcuno può darmi un esempio di distinzione tra il passaggio di un tipo come secondo argomento rispetto al passaggio di un oggetto?

La documentazione parla di un'istanza di un oggetto?

Grazie.

+9

Questo dovrebbe dare qualche prospettiva: http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html#object-type-example – karthikr

+0

@karthikr D'accordo, grande articolo – jamylak

+3

Oppure dare un'occhiata a questa domanda http: //stackoverflow.com/questions/100003/what-is-a-metaclass-in-python?rq=1 e la grande risposta, mentre riguarda le metaclassi, specifica i tipi e gli oggetti per costruire la descrizione di un metaclass - davvero buono leggere. –

risposta

0

L'oggetto può essere una qualsiasi istanza di classe Python che può o non può essere definita dall'utente. Ma, quando si sta parlando di un tipo , si riferisce agli oggetti predefiniti/collezioni come un elenco/tupla/dict/int/str ecc

+0

Mi permetto di dissentire, è ** non ** limitato ai builtin. Ognuno può e definisce i propri tipi. – delnan

+0

@smitkpatel, penso che potresti pensare ai tipi "incorporati". – Demolishun

+0

builtin - default potato - potato – smitkpatel

0

Ecco una semplice esplorazione delle due funzioni. L'ho trovato illuminante durante questo esercizio. Spesso mi creerò un semplice programma di esplorare gli angoli più riposti di funzioni semplici e salvarli per riferimento:

# 
# Testing isinstance and issubclass 
# 

class C1(object): 
    def __init__(self): 
     object.__init__(self) 

class B1(object): 
    def __init__(self): 
     object.__init__(self) 

class B2(B1): 
    def __init__(self): 
     B1.__init__(self) 

class CB1(C1,B1): 
    def __init__(self): 
     # not sure about this for multiple inheritance 
     C1.__init__(self) 
     B1.__init__(self) 

c1 = C1() 
b1 = B1() 
cb1 = CB1() 

def checkInstanceType(c, t): 
    if isinstance(c, t): 
     print c, "is of type", t 
    else: 
     print c, "is NOT of type", t 

def checkSubclassType(c, t): 
    if issubclass(c, t): 
     print c, "is a subclass of type", t 
    else: 
     print c, "is NOT a subclass of type", t 

print "comparing isinstance and issubclass" 
print "" 

# checking isinstance 
print "checking isinstance" 

# can check instance against type 
checkInstanceType(c1, C1) 
checkInstanceType(c1, B1) 
checkInstanceType(c1, object) 

# can check type against type 
checkInstanceType(C1, object) 
checkInstanceType(B1, object) 

# cannot check instance against instance 
try: 
    checkInstanceType(c1, b1) 
except Exception, e: 
    print "failed to check instance against instance", e 

print "" 

# checking issubclass 
print "checking issubclass" 

# cannot check instance against type 
try: 
    checkSubclassType(c1, C1) 
except Exception, e: 
    print "failed to check instance against type", e 

# can check type against type 
checkSubclassType(C1, C1) 
checkSubclassType(B1, C1) 
checkSubclassType(CB1, C1) 
checkSubclassType(CB1, B1) 

# cannot check type against instance 
try: 
    checkSubclassType(C1, c1) 
except Exception, e: 
    print "failed to check type against instance", e 

Edit: Considera anche quanto segue come isinstance può rompere implementazioni API. Un esempio potrebbe essere un oggetto che si comporta come un dizionario, ma non è derivato da dict. isinstance potrebbe verificare che un oggetto è un dizionario, anche se l'oggetto supporta dizionario accesso stile: isinstance considered harmful

Edit2:

Qualcuno può per favore mi dia un esempio di una distinzione tra il superamento di un tipo come un secondo argomento contro il superamento di un oggetto?

Dopo aver testato il codice precedente, il secondo parametro deve essere un tipo. Quindi nel seguente caso:

checkInstanceType(c1, b1) 

La chiamata avrà esito negativo. Potrebbe essere scritto:

checkInstanceType(c1, type(b1)) 

Quindi, se si desidera controllare il tipo di un'istanza contro un altro esempio è necessario utilizzare il tipo() chiamata incorporato.

3

La funzione di Python super fa cose diverse a seconda di quali sono gli argomenti.Ecco una dimostrazione di diversi modi di utilizzo: uscita

class Base(object): 
    def __init__(self, val): 
     self.val = val 

    @classmethod 
    def make_obj(cls, val): 
     return cls(val+1) 

class Derived(Base): 
    def __init__(self, val): 
     # In this super call, the second argument "self" is an object. 
     # The result acts like an object of the Base class. 
     super(Derived, self).__init__(val+2) 

    @classmethod 
    def make_obj(cls, val): 
     # In this super call, the second argument "cls" is a type. 
     # The result acts like the Base class itself. 
     return super(Derived, cls).make_obj(val) 

prova:

>>> b1 = Base(0) 
>>> b1.val 
0 
>>> b2 = Base.make_obj(0) 
>>> b2.val 
1 
>>> d1 = Derived(0) 
>>> d1.val 
2 
>>> d2 = Derived.make_obj(0) 
>>> d2.val 
3 

Il risultato 3 è la combinazione dei modificatori precedenti: 1 (da Base.make_obj) più 2 (da Derived.__init__).

Si noti che è possibile chiamare super con un solo argomento per ottenere un oggetto super "non associato", apparentemente non è utile per molto. Non c'è davvero alcun motivo per farlo a meno che tu non voglia gironzolare con interni di Python e tu, , davvero sai cosa stai facendo.

In Python 3, è anche possibile chiamare super senza argomenti (che equivale a fornire la classe corrente e self come due argomenti, ma più magico).

+0

È un eccellente modo di aiutare con la Memoizzazione delle chiamate di funzione? Ho un oggetto che accelera le chiamate a un altro interprete controllando la presenza delle funzioni e quindi assegnando un attributo all'oggetto con un oggetto che chiama direttamente la funzione. Quindi fondamentalmente cerco solo la funzione una volta e la memoize a un attributo callable. Devo usare object .__ setattr __ (self, "attribute", callableObj) per impedirgli di ripetere/chiamare la mia ridefinizione di "__settr__". Super fa la stessa cosa? – Demolishun

+0

@Demolishun: Um, no. Si usa 'super' per ottenere le versioni ereditate dei metodi sovrascritti. Controlla [i documenti] (http://docs.python.org/2/library/functions.html#super) – Blckknght

+0

Ok, quindi è simile, ma consente il riferimento dinamico della classe base, ma non per nome . Questo è un caso d'uso. http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ Grazie per il ref. – Demolishun

Problemi correlati