In Python, c'è qualche differenza (a parte alcune eccezioni elencate) tra classi e dizionari?

4

La mia logica va così:

def A(val):
    return {'a':val}

print(A(7)['a'])

è uguale a

class A:
    def __init__(self, val):
        self.a = val

print(A(7).a)

Ovviamente, ci sono problemi e alcune differenze:

  • Questo vale solo per le lingue come python in cui è possibile creare un dizionario con tipi diversi in esso.
  • La sintassi della creazione di un 'oggetto'. Questo è il motivo (credo) che le classi siano superiori, perché usare una funzione per creare classi diventerebbe rapidamente molto irritante.
  • Trattamenti speciali per scorciatoie. Come str (x) chiama __str__ e obj.function () cambia in cls.function (obj).
  • Inheritance.
  • Oggetti di classe reali (se A è la classe, puoi ottenere A .__ init__ (ad esempio) come metodo non associato.

A parte questi piccoli casi, dizionari == classi (per me). Sei d'accordo con me?

    
posta user3808430 10.11.2014 - 22:13
fonte

2 risposte

2

Puoi pensare a un oggetto o come entità contenente

  1. una raccolta di variabili locali v1, v2, ... (lo stato dell'oggetto),
  2. una raccolta di chiusure m1, m2, ... che si chiudono su v1, v2, m1, m2 (i metodi dell'oggetto),
  3. un meccanismo per accedere alla variabile locale e ai metodi per nome: un oggetto è fondamentalmente una funzione di ordine superiore che prende un nome come input e restituisce un campo o un metodo come risultato.

In un oggetto Python usi la notazione a punti (o.var, o.foo ()) per accedere a membri e metodi. Naturalmente, puoi facilmente simularlo con un dizionario come hai descritto: un dizionario è anche una mappatura (vedi punto 3) e puoi usarlo per memorizzare campi o metodi oggetto.

Quindi direi che il costrutto di classe è una sintassi più comoda per esprimere il modello dell'oggetto. Puoi simulare anche gli oggetti con i dizionari, diventa solo più dettagliato.

The syntax of creating an 'object'. This is the reason (I think) classes are superior, because using a function to create classes would quickly become very irritating.

Invece di avere funzioni per creare classi, immagino di usare le funzioni per creare oggetti (cioè dizionari speciali), che corrisponderebbero ai costruttori di classi. Guarda anche il tuo esempio: function A() è la funzione di costruzione corrispondente al metodo __init__() della classe A .

Inheritance.

Penso che se modellate le classi con funzioni di costruzione che restituiscono dizionari, potete modellare l'ereditarietà usando il costruttore della superclasse nel costruttore della sottoclasse. Il costruttore della sottoclasse può chiamare il costruttore della superclasse e quindi estendere / sovrascrivere il dizionario risultante con le proprie definizioni.

Ad esempio:

# Superclass A.
def A(val):
    def toString(a):
        return str(a['a'])

    def printOut(a):
        print(a['toString'](a))

    return {'a': val, 'toString': toString, 'printOut': printOut}

# B is a subclass of A.
def B(val):
    # Override method.
    def toString(a):
        return 'value = ' + str(a['a'])

    r = A(val)
    r['toString'] = toString
    return r

Riassumendo, non direi che i dizionari sono uguali alle classi:

  • Un dizionario è una mappatura arbitraria.
  • Un oggetto è una mappatura speciale dai nomi alle variabili e ai metodi.
  • Una classe è un costrutto linguistico che raccoglie oggetti con struttura simile e aiuta a creare oggetti.
  • Oggetti e classi possono essere simulati in modo semplice usando funzioni e dizionari.
risposta data 10.11.2014 - 22:34
fonte
4

Hai ragione. Gli oggetti nei linguaggi dinamici si sono evoluti da, e in qualche modo assomigliano, oggetti dizionario / mappatura di fantasia. Questo è molto vero per i linguaggi basati su prototipi come JavaScript, e ancora vero per i linguaggi basati su classi come Python e Ruby.

Tuttavia, la domanda è eccessivamente riduttiva. Chiedi "c'è qualsiasi differenza?" solo per escludere rapidamente alcune differenze molto importanti. Funzionalità come ereditarietà (Python ha un sistema di eredità multipla elaborato con ampio supporto per metaclassi) e l'elaborazione speciale dei metodi di dunder non sono inezie . Sono vasti corpi di lavoro che definiscono gran parte della semantica, delle operazioni e dell'estensibilità del linguaggio.

Potresti avere un elenco di altri modi in cui le classi Python sono diverse, come la capacità di

  1. Intervenire al momento della creazione dell'oggetto e riorganizzare sistematicamente il modo in cui gli oggetti vengono creati (metaclassi),
  2. Utilizza rappresentazioni statiche, non di dizionario (slot),
  3. Accedi ai membri tramite la notazione degli attributi ( obj.attr ),
  4. Specializza gli attributi funzionali (metodi aka) come proprietà virtuali ( @property ), classe piuttosto che metodi di istanza ( @classmethod ) o funzioni normali relative alla classe ( @staticmethod ).

Potremmo elencare ancora più modi in cui le classi sono diverse dal semplice "syntax sugar" in cima ai dizionari. E l'opzione di utilizzare un'implementazione con fessura, senza dizionario dovrebbe sigillare l'accordo. Ma tali elenchi mancano il numero uno:

Le classi definiscono nuovi tipi di dati.

Classi e oggetti possono essere, a un certo livello, solo dizionari fantasiosi, ma sono sufficientemente evoluti da diventare qualcos'altro interamente.

Le classi definiscono nuovi tipi di dati. In tutte le versioni recenti del linguaggio - 2.x avanti, usando "nuovi oggetti di stile" che sottoclasse object - le classi definite dall'utente sono in gran parte equivalenti e completamente parallele con i tipi di dati incorporati. Puoi chiedere type(x) e instance(x, (int, str, MyClass)) , interagendo con classi e istanze proprio come fai con i tipi di dati incorporati e i loro valori. Ciò non è possibile nella maggior parte dei linguaggi statici tradizionali, dove potresti essere in grado di creare nuovi tipi di dati astratti , ma non saranno mai , essere sempre paragonabile a, o flessibile come, i tipi predefiniti.

Full disclosure: ci sono alcune differenze rimanenti, in gran parte sottili, e per lo più basate sul fatto che i tipi integrati sono implementati "sotto le copertine" in C, e non sono oggetti Python. di per sé.

Ma in gran parte, le classi sono diverse dai dizionari in modi che pervadono la progettazione linguistica e che mettono le loro e le loro istanze alla pari con i tipi di definizione della lingua. In Python, la loro somiglianza con la mappatura degli oggetti è decisamente secondaria.

    
risposta data 10.11.2014 - 23:27
fonte

Leggi altre domande sui tag