Perché abbiamo i metodi dei mutatori?

4

Sto passando da Java a Python e sto avendo problemi a capire il decoratore @Property . Ho realizzato in linguaggi OOP (come Java) non capisco appieno il punto dei metodi mutator nel senso seguente:

Supponiamo di avere una variabile privata x . Quindi dobbiamo creare un metodo mutatore

public void setX(int val) {
  x = val;
}

Ora se x era stato public allora avremmo potuto fare solo x = val e sarebbe stato più semplice e non ci sarebbe stata alcuna differenza. Ora, in uno scenario più complicato, potremmo aggiungere restrizioni, forse non ha senso che x sia inferiore a 10

public void setX(int val) {
  if(x < 10)
    x = 10;
  else
    x = val;
}

Quindi in un certo senso è il punto di avere metodi mutator per imporre restrizioni sui dati? Quindi è per ottenere l'incapsulamento? Ci sto pensando perché con @Property di Python (correggimi se ho torto) non stai chiamando un metodo mutatore ma in effetti funziona allo stesso modo, nel senso che può avvenire una logica addizionale prima che il valore venga cambiato.

Una domanda corollaria è, se abbiamo un semplice metodo di mutatore come nel primo esempio, la variabile dovrebbe essere resa pubblica?

    
posta northerner 18.04.2017 - 00:41
fonte

2 risposte

7

Per prima cosa devi rispondere alla tua ultima domanda - in Java dovresti sempre usare i metodi accessor e mutator, perché se fai un campo pubblico e dopo decidi che ha bisogno di una logica extra - avrai un brutto momento. Se sei fortunato e il tuo codice non è una biblioteca, tutto ciò che serve è la pulizia del prodotto di costruzione, la ricostruzione e l'attraversamento di innumerevoli luoghi in cui accedi a quella variabile, cambiandoli a mano. Se sei una biblioteca, anche se fortuna. Stai per infrangere il codice degli utenti ...

In Python - non importa. La sintassi degli attributi (e l'implementazione AFAIK) è la stessa per i campi e le proprietà. L'unica differenza è se il tuo metodo personalizzato verrà chiamato o il __getattribute__ /%% di default che guarderà all'interno di __setattribute__ (o ne imposterà un valore). Quindi, se non hai bisogno di una logica extra, usa solo un campo regolare. Puoi sempre modificarlo in seguito.

Per quanto riguarda il "perché" - il motivo più comune per usare un __dict__ in Python è che non si memorizza il valore diretto reale all'interno dell'oggetto.

Ad esempio:

class Vector2D(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def length(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5

    @length.setter
    def length(self, value):
        multiplier = value / self.length
        self.x *= multiplier
        self.y *= multiplier

Non memorizziamo direttamente @property - memorizziamo solo length e x . Ma possiamo ancora ottenere e impostare la lunghezza come se fosse una proprietà ordinaria - e il nostro codice y fa il lavoro dietro le quinte per noi.

    
risposta data 18.04.2017 - 01:19
fonte
2

Come indicato qui:

link

Ho anche visto il decoratore @property utilizzato per indicare che un campo è "di sola lettura". Ad esempio:

class Thing(object):
    def __init__(self, path):
        self._path = path

    @property
    def path(self):
        return self._path

Naturalmente, siamo tutti adulti consenzienti in Python e questo non è in realtà di sola lettura, ma non sarà possibile assegnarlo tramite la proprietà path , solo attraverso il campo _path .

    
risposta data 18.04.2017 - 07:26
fonte

Leggi altre domande sui tag