2015-03-01 7 views

risposta

9

Un attributo è una variabile che viene cercata su un altro oggetto utilizzando la sintassi del punto: obj.attribute. Il modo in cui Python è progettato, la ricerca degli attributi può fare una varietà di cose e questa varietà a volte può portare a bug se non capisci cosa sta accadendo (questo è ciò che la documentazione che hai collegato per avvisare).

Il problema di base è che una ricerca di attributi può trovare un valore memorizzato nel dizionario di istanza dell'oggetto oppure può trovare qualcosa dalla classe dell'oggetto (o una classe base, se c'è un'eredità in corso). I metodi sono funzioni memorizzate nella classe, ma di solito li usi osservandoli su un'istanza (che "lega" il metodo, inserendo l'oggetto come prima arguemnt quando viene chiamato il metodo).

L'esatta sequenza di ciò che viene controllato quando è un po 'complicato (ho descritto l'intero processo in an answer to another question), ma al livello di base, gli attributi di istanza hanno la precedenza sull'attributo di classe.

Se un attributo di istanza e un attributo di classe con lo stesso nome esistono entrambi, in genere solo l'attributo di istanza sarà accessibile. Questo può essere molto confuso se non è intenzionale.

Si consideri il seguente codice:

class Foo(object): 
    def __init__(self, lst): 
     self.lst = lst 

    def sum(self): 
     self.sum = sum(self.lst) 
     return self.sum 

f = Foo([1,2,3]) 

print(f.sum()) 
print(f.sum()) 

Al fondo di questo codice, facciamo due chiamate identici. Il primo funziona bene, ma il secondo solleverà un'eccezione.

Questo perché la prima volta che cerchiamo f.sum troviamo un metodo nella classe Foo. Possiamo chiamare il metodo senza problemi. Il problema deriva dal fatto che il metodo sum assegna il risultato del suo calcolo (la somma degli elementi in self.lst) a un attributo di istanza chiamato anche sum. Nasconde il metodo sum dalla vista.

Quando la seconda chiamata f.sum() ricerca f.sum, trova l'attributo di istanza, contenente il numero intero 6, anziché il metodo previsto. Un numero intero non è chiamabile, quindi otteniamo un'eccezione.

La soluzione, ovviamente, non è quella di utilizzare lo stesso nome per il metodo e l'attributo. Il codice sopra è un esempio piuttosto banale. Gli errori causati da questo tipo di cose in codice più complesso possono essere molto più difficili da capire.

Se si scrive codice che aggiunge attributi a oggetti di cui non si conosce molto, è necessario fare attenzione a evitare nomi comuni. Se stai scrivendo una lezione di mixin, considera l'uso di due trattini bassi di sottolineatura nei nomi degli attributi per attivare il mangling del nome di Python, che è progettato proprio per questo tipo di situazione.

+0

La tua spiegazione è piuttosto semplice. Quindi, mi sembra che la documentazione che ho collegato voglia dire "attributo dati" = "attributo istanza", "attributo metodo" = "attributo classe". Se sbaglio, correggimi. –

+0

Sì, è vero. Penso che la documentazione potrebbe essere piuttosto vecchia e non del tutto aggiornata. Certamente, "attributo di istanza" e "attributo di classe" sono termini molto più comuni al giorno d'oggi. Vale anche la pena notare che la situazione reale è un po 'più complicata di quella che ho presentato qui. Alcuni tipi di attributi di classe (ad esempio oggetti 'proprietà') avranno la precedenza sugli attributi di istanza. È improbabile che tu finisca in quella situazione per sbaglio, comunque. – Blckknght

3

Un attributo è qualsiasi cosa per la mancanza di una parola migliore che si associa a un oggetto, ad esempio:

class Dog: 
    def __init__(self): 
     self.name = "Rufus" 

    def bark(self): 
     print "Woof Woof!" 

In questo caso l'attributo di dati è il nome, che è semplicemente un valore che è legato all'istanza del Cane. Per quanto riguarda un attributo del metodo, una risposta sarebbe il metodo della corteccia, poiché non è tanto un valore quanto un'azione. È proprio come è in inglese. Un attributo di dati è esattamente come sembra; è dati, è semplicemente una proprietà. Un metodo è una procedura, un'azione e questo è esattamente ciò che è un attributo del metodo.

1

Un attributo è praticamente tutto ciò che è possibile fare con instance.attribute_name. Per esempio in:

class Hello(object): 
    def __init__(self, word): 
     self.word = word 

    def greet(self): 
     print "Hello: "+self.word 

__init__, greet e word sarebbero tutti gli attributi. Direi che un metodo è qualsiasi cosa dichiarata con def nell'ambito della classe (al contrario di fare self.func = lambda x: x * x per esempio). In questo caso, si ottengono metodi vincolati, non associati e simili. La parte importante è che per un attributo membro quando si esegue instance.method_name si ottiene un metodo associato, che quando viene chiamato chiamerà il metodo originale con l'istanza come primo argomento.

Inoltre, dopo aver letto parte di quella sezione, la loro formulazione è alquanto confusa/errata. Ad esempio, dicono "Gli attributi dei dati sostituiscono gli attributi del metodo con lo stesso nome", che per quanto ne so sarebbe meglio mettere come attributo di istanza sovrascrivere gli attributi di classe con lo stesso nome. Dall'esempio ho dato se abbiamo ampliato questo:

class Hello(object): 
    greeting = "Hello: " 
    def __init__(self, word): 
     self.word = word 

    def greet(self): 
     print self.greeting+self.word 

Allora potremmo fare:

>>> a = Hello("world") 
>>> a.greeting = "Goodbye " 
>>> a.greet() 
"Goodbye world" 

Ciò a causa del fatto che abbiamo messo un attributo un'istanza di saluto sopra l'attributo di classe di saluto. Poiché i metodi definiti nella classe (nel modo usuale) sono attributi di classe, verranno sovrascritti da tutti gli attributi di istanza (dati o altro).

0

Ecco una spiegazione semplice alla tua domanda, che mi ha aiutato a capire la differenza tra un attributo e un metodo.

Una classe è come un insieme di istruzioni o un modello per come creare molti oggetti che condividono le caratteristiche.

Un oggetto è un tipo di dati costruito in base alle specifiche fornite dalla definizione della classe.

Un attributo è un valore (caratteristica). Pensa a un attributo come una variabile che è memorizzata all'interno di un oggetto.

Un metodo è un insieme di istruzioni. I metodi sono funzioni, che sono associate a un oggetto. Qualsiasi funzione inclusa nella definizione della classe genitore può essere chiamata da un oggetto di quella classe.

Spero che questo aiuti.