2009-03-08 11 views
21

Ho questo codice:Perché non posso aggiungere direttamente attributi a qualsiasi oggetto Python?

>>> class G: 
... def __init__(self): 
...  self.x = 20 
... 
>>> gg = G() 
>>> gg.x 
20 
>>> gg.y = 2000 

E questo codice:

>>> from datetime import datetime 
>>> my_obj = datetime.now() 
>>> my_obj.interesting = 1 
*** AttributeError: 'datetime.datetime' object has no attribute 'interesting' 

Dalla mia conoscenza di Python, direi che datetime override setattr/getattr, ma non sono sicuro. Potresti fare un po 'di luce qui?

EDIT: Non sono specificamente interessato a datetime. Mi stavo chiedendo degli oggetti in generale.

+0

"Mi chiedevo di oggetti in generale." Che cosa? Mostra un esempio generale di una classe generale che generalmente ha aggiunto degli attributi. Che cosa significa la tua modifica? –

+3

Significa che ero curioso di tutte le classi, non solo di datetime. Ho postato questa domanda perché ho visto che ad alcune classi potevo aggiungere attributi, mentre ad altri non potevo. – Geo

+0

@Geo: alcune classi sono diverse: non esiste una regola "generale". Come nota la tua domanda: alcune classi possono e alcune classi non possono. Dal momento che la tua domanda mostra che non esiste una regola generale, cosa stai chiedendo? –

risposta

32

La mia ipotesi è che l'implementazione di datetime utilizza __slots__ per prestazioni migliori.

Quando si utilizza __slots__, l'interprete riserva l'archiviazione solo per gli attributi elencati, nient'altro. Ciò offre prestazioni migliori e utilizza meno spazio di archiviazione, ma significa anche che non è possibile aggiungere nuovi attributi a piacimento.

Per saperne di più qui: http://docs.python.org/reference/datamodel.html

+10

Datetime è in realtà scritto in C, che offre un comportamento molto simile alla scrittura di un oggetto python che utilizza __slots__. Gli slot sono un modo di scrivere oggetti in python che sono quasi efficienti quanto le versioni C, senza ricorrere a c –

+6

Quindi si può vedere il comportamento perché l'oggetto è scritto in c, perché usa setattr, o per le slot :-) –

3

Mentre la domanda è già stata risolta; se qualcuno è interessato a una soluzione alternativa, ecco un esempio:

mydate = datetime.date(2013, 3, 26) 
mydate.special = 'Some special date annotation' # doesn't work 
... 
class CustomDate(datetime.date): 
    pass 
mydate = datetime.date(2013, 3, 26) 
mydate = CustomDate(mydate.year, mydate.month, mydate.day) 
mydate.special = 'Some special date annotation' # works 
+0

È legittimo? (Voglio dire, non ha degli svantaggi?) – gabn88

+1

Sì, è legittimo – s29

+0

Devi amarlo! – gabn88

Problemi correlati