C'è qualche buona ragione per cui i classvari Python e l'ereditarietà del prototipo di JavaScript non mutano il genitore al momento dell'assegnazione?

4

In Python, se si dispone di un classvar, è accessibile da un'istanza, ma se si imposta la variabile sull'istanza in realtà non cambia il classvar, piuttosto assegna un nuovo nome che ombreggia il valore genitore:

>>> class Foo:
...     classvar = 10
...
>>> f = Foo()
>>> (Foo.classvar, f.classvar)
(10, 10)
>>> f.classvar = 30
>>> (Foo.classvar, f.classvar)
(10, 30)
>>> Foo.classvar = 9
>>> (Foo.classvar, f.classvar, Foo().classvar)
(9, 30, 9)

Questo è esattamente simile all'ereditarietà del prototipo in JavaScript:

> var proto = {x: 10};
> function Bar() { }
> Bar.prototype = proto;
> var b = new Bar(); 
> [proto.x, b.x]
[10, 10]
> b.x = 30
> [proto.x, b.x]
[10, 30]
> proto.x = 9
> [proto.x, b.x, (new Bar()).x]
[9, 30, 9]

Naturalmente, se il bambino modifica il valore , viene visualizzato nel genitore, poiché la variabile non è stata nuovamente assegnata e quindi non si è verificato alcuno shadowing:

>>> class Foo:
...     classvar = [10]
...
>>> f = Foo(); f.classvar
[10]
>>> f.classvar[0] = 30
>>> (Foo.classvar, f.classvar)
([30], [30])

La mia domanda è: c'è qualche buona ragione per questo? Sembra che sarebbe meno un "getcha" se la semantica di assegnazione fosse "assegna a qualsiasi genitore se il valore esiste lì, altrimenti crea il nuovo valore".

Te lo chiedo perché sto progettando la mia lingua e, non appena avrò scelto cosa sia la semantica, mi chiederò se dovrei rompere dalla mandria e fare quello che sembra meno di un trucchetto.

    
posta Claudiu 20.12.2016 - 06:40
fonte

2 risposte

4

Perché se mutando l'istanza mutasse il "genitore" non ci sarebbe alcun punto nell'avere istanze. Il punto di un'istanza è che ha la sua memoria. È libero di essere diverso. Il "genitore" fornisce solo valori iniziali predefiniti.

Se il "genitore" e l'istanza puntano entrambi sulla stessa cosa, allora condividono la memoria di quella cosa, quindi non dovrebbe sorprendere che cambino da un impatto all'altro.

    
risposta data 20.12.2016 - 07:32
fonte
1

Alla fine ho concluso così:

Se l'impostazione su un bambino ha il comportamento di "impostato su genitore se genitore ha, altrimenti impostato su se stesso", allora è impossibile che un bambino non sostituisca un valore genitore. Inoltre, l'assegnazione non è affatto semplice.

Tuttavia, se il comportamento è normale, l'assegnazione è molto semplice, sempre assegnata a se stessi. Nel caso in cui si desidera ombreggiare un nome genitore, è possibile. Nel caso menzionato nella domanda in cui vuoi mutare un immutabile, allora devi fare un work-around avvolgendo l'immutabile in un contenitore. Quindi hai un work-around per tutto ciò che vuoi, mentre l'altro ti limita, è non standard e ha semantica meno semplice.

    
risposta data 20.12.2016 - 11:33
fonte