2010-07-16 15 views
9

Questa è una domanda suggerita da another question da parte mia.Django Abstract Models vs simple Python mixins vs Python ABC

Django fornisce la funzionalità Abstract base classes (che non è uguale alle classi ABC in Python?) In modo che si possa creare un modello (modelli Django.Modello) da cui si può ereditare, ma senza che il Modello abbia una tabella effettiva nel Banca dati. Si innesca questo comportamento impostando l'attributo 'abstract' nella classe Meta del modello.

Ora la domanda: perché Django lo risolve in questo modo? Perché la necessità di questo speciale tipo di modello di "classe base astratta"? Perché non creare un mixin del modello semplicemente ereditando dalla classe dell'oggetto e mescolandolo con un modello esistente? O potrebbe anche questo compito di un Python ABC? (Si badi bene non sono molto familiarità con le classi ABC in Python, la mia ignoranza potrebbe mostrare qui)

risposta

11

Cercherò di essere ragionevolmente brevi, dal momento che questo può facilmente trasformarsi in una lunga diatriba:

ABC sono perché sono stati introdotti solo in Python 2.6 e gli sviluppatori di Django hanno una roadmap predefinita per il supporto della versione Python (il supporto 2.3 è stato abbandonato solo in 1.2).

Per quanto riguarda le miscele che ereditano oggetti, sarebbero meno Pythonic in più di una semplice riduzione della leggibilità. Django utilizza un metacarattere ModelBase per gli oggetti Model, che analizza effettivamente le proprietà del modello definito all'inizializzazione e popola Model._meta con i campi, le opzioni Meta e altre proprietà. Ha senso riutilizzare quella struttura per entrambi i tipi di modelli. Ciò consente inoltre a Django di impedire che i campi del modello astratto vengano ignorati ereditando i modelli.

Ci sono molte più ragioni a cui riesco a pensare, tutte in sé minori, ma si sommano per rendere l'implementazione attuale molto più Pythonic. Non c'è niente di intrinsecamente sbagliato nell'usare mixini che ereditano oggetti.

+0

(Contrassegnare come risposta accettata, sebbene anche Daniel sia buono, ma Aram ha ampliato un po 'di più i grintosi bit.) Ho ragione nel capire che, usando i mixin ereditari di oggetti, sarei in grado di dichiarare campi extra sul modello? Ma sarei in grado di aggiungere metodi aggiuntivi o sovrascriverli? – hopla

+0

Sì, i mixins che ereditano oggetti possono dichiarare campi e metodi aggiuntivi. Puoi sovrascrivere i metodi assicurandoti che il tuo mix-in che eredita gli oggetti venga prima nell'elenco delle classi da cui ereditare. Tuttavia, indipendentemente dall'ordine, un mixin che eredita oggetti non può sovrascrivere un campo (non mancherà di convalidare se tenta di farlo). –

6

Uno dei motivi è dovuto al modo in cui i campi sono definiti su un modello.

I campi sono specificati in modo dichiarativo, in modo che una classe normale possa trattare come attributi di classe. Tuttavia devono diventare attributi di istanza per quando la classe viene effettivamente istanziata, in modo che ogni istanza possa avere il proprio valore per ogni campo. Questo è gestito tramite il metaclass. Questo non funzionerebbe con una normale classe di base astratta.