2012-04-11 7 views
7

Ogni classe in python eredita dalla classe 'oggetto'. Mi sto interrogando sul meccanismo interno dell'implementazione della classe "oggetto". Perché la classe 'oggetto' non può essere assegnata a nessun attributo utente? Sono convinto che sia legato alla gestione della memoria, ma se l'utente pensa di implementare la gestione della memoria, perché non può ignorare la classe "object" in python? Questo è basato sul mio interesse e voglio sapere su quale potrebbe non avere un'applicazione programmatica, ma sarebbe bello conoscere la funzionalità interna della lingua stessa.perché la classe 'oggetto' non ha attributi impostati dall'utente

+2

In realtà, in Python 2.x, solo le classi di nuovo stile ereditano da '' object''. (Bene, e in Python 3.x, ma tutte le classi sono di nuovo stile, quindi è inutile menzionarlo). –

+1

Questa non è una buona ragione per un downvote - ma è un ottimo posto per una risposta per educare il richiedente ... sembra una domanda ben pensata e valida per me. +1 – ImGreg

+1

Jack, puoi chiarire se stai parlando di aggiungere attributi alla classe dell'oggetto o alle istanze di quella classe? –

risposta

1

Se dovessi ricavare il ragionamento da principi primi, potrei pensare in termini di meccanismo di __slots__. Alcuni tipi di classi hanno bisogno solo di un piccolo numero di attributi, e l'insieme di attributi è sempre fissato per ogni istanza, e quindi la flessibilità di una funzionalità di attributi utente "dict" sarebbe sprecare di cpu (cercare attributi con nomi dinamici) e spazio (il sovraccarico di un dict vuoto, piccolo ma non zero), che può davvero aggiungere un sacco di spese generali se ci sono un gran numero di istanze.

ovviamente questo è esattamente il problema risolto dal meccanismo __slots__. lo spazio è allocato sull'oggetto per gli attributi definiti negli slot. se è presente un attributo __dict__, è possibile trovare gli attributi non slot e, se non esiste alcun attributo __dict__, non si ottengono né gli attributi dinamici né il costo dell'oggetto dict non necessario (che è un oggetto heap aggiuntivo diverso dall'istanza stessa).

Per quanto riguarda il motivo per cui object sé non ha uno slot per __dict__, bene, anche se una sottoclasse ha indicato che non l'hanno fatto necessità il __dict__ fessura, se ereditare da una classe che fa , quindi l'istanza deve ancora avere un __dict__; seavesse un __dict__ allora ogni classe pagherebbe anche il prezzo di uno __dict__, anche se non ne aveva bisogno.

Invece; le sottoclassi ottengono __dict__ (e __weakref__, per ragioni analoghe) a meno che esse non definiscano un attributo di classe __slots__.

E perché è necessaria una semplice istanza di object? Hai solo bisogno di un sacco di attributi? bene quindi utilizzare un dict. Se hai effettivamente bisogno di un oggetto di qualche tipo con comportamenti e attributi, allora stai comunque creando una sottoclasse.

Circa l'unico motivo che posso immaginare con object() invece di una sottoclasse di object, è quando l'unica caratteristica dell'istanza che è di interesse è la sua identità. Questo sarebbe venuto quando una funzione prende argomenti, e per i quali None o qualche altro valore sentinella ovvio dovrebbe essere inteso come distinto dal default:

BAR_DEFAULT = object() 
def foo(bar=BAR_DEFAULT): 
    if bar is BAR_DEFAULT: 
     #... 

In questo caso è né necessario né particolarmente desidera attributi nella istanza di object,

3

I tipi definiti in C non possono mai avere attributi assegnati dall'utente. Se si desidera sostituire object a livello globale, è necessario eseguire iterazioni su ogni singola classe esistente, quindi sostituire __builtin__.object per catturare tutta la creazione futura della classe. E anche questo non è affidabile poiché il vecchio oggetto potrebbe essere associato altrove.

3

Questo è stato discusso su StackOverflow, ma non riesco a trovare la discussione per collegarlo.

La ragione per cui mi sono chiesto è perché ho voluto semplificare questo esempio:

class Box(object): 
    pass 

box = Box() 
box.a = "some value" 
box.b = 42 

Qui sto usando box come una sorta di dizionario, quella in cui le chiavi possono essere solo identificatori. Lo faccio perché è più conveniente scrivere box.a rispetto a box["a"].

ho voluto fare questo:

box = object() 
box.a = "some value" # doesn't work 

La ragione è che object è la radice di tutti gli oggetti in Python. Qualsiasi attributo che object deve avere in qualsiasi tipo derivato. Se si desidera creare un elenco di grandi dimensioni contenente un numero elevato di oggetti, si desidera che siano il più piccolo possibile in modo da non esaurire la memoria. Quindi lo object è minimo.

EDIT: ho trovato il link stavo cercando di ricordare:

struct objects in python

Problemi correlati