Domanda

Ho definito una classe Vector che ha tre variabili di proprietà: x, y e z. Coordinate devono essere numeri reali, ma non c'è nulla per fermare uno di fare il seguente:

>>> v = Vector(8, 7.3, -1)
>>> v.x = "foo"
>>> v.x
"foo"

ho potuto attuare "la sicurezza di tipo" come questo:

import numbers

class Vector:
    def __init__(self, x, y, z):
        self.setposition(x, y, z)

    def setposition(self, x, y, z):
        for i in (x, y, z):
            if not isinstance(i, numbers.Real):
                raise TypeError("Real coordinates only")

        self.__x = x
        self.__y = y
        self.__z = z

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @property
    def z(self):
        return self.__z

... ma che sembra non-Pythonic.

Suggerimenti?

È stato utile?

Soluzione

È necessario chiedersi perché si vuole tipo di test su come impostare questi valori. Basta sollevare un TypeError in qualsiasi calcolo che succede ad inciampare il torto Valore tipo. Bonus:. Operazioni standard già fanno questo

>>> 3.0 / 'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for /: 'float' and 'str'

Altri suggerimenti

duck typing è il solito modo in Python. Dovrebbe funzionare con qualsiasi cosa che si comporta come un numero, ma non necessariamente un numero reale.

Nella maggior parte dei casi in Python non si dovrebbe verificare esplicitamente per i tipi. Si guadagna flessibilità, perché il codice può essere utilizzato con tipi di dato personalizzati, a patto che si comportano correttamente.

Le altre risposte già sottolineato che non ha molto senso per verificare il tipo di qui. Inoltre, la classe non sarà molto veloce se è scritto in puro Python.

Se si desidera una soluzione più divinatorio - si potrebbe usare setter proprietà come:

@x.setter
def x(self, value):
    assert isinstance(value, numbers.Real)
    self.__x = value

verrà rimossa L'istruzione assert quando il debug disabilitare o abilitare il modo di ottimizzazione.

In alternativa, si potrebbe costringere value a virgola mobile nel setter. Che aumenterà un'eccezione se il tipo / valore non è convertibile:

@x.setter
def x(self, value):
    self.__x = float(value)
  

Ma non c'è nulla per fermare uno di fare il seguente:

Credo che cercare di impedire a qualcuno di fare qualcosa del genere è un-Pythonic. Se è necessario, allora si dovrebbe verificare per la sicurezza di tipo durante il qualsiasi operazione si potrebbe fare usando Vector, a mio parere.

Per citare G.V.R:

  

siamo tutti adulti.

dopo tutto. Vedere questo domanda e le sue risposte per ulteriori informazioni.

Sono sicuro più esperti Pythonisti qui può dare risposte migliori.

Non sono tenuti a fornire la sicurezza di tipo in questo modo. Sì, qualcuno può deliberatamente rompere il codice fornendo valori per i quali il vostro contenitore non funzionerà - ma questo è solo la stessa cosa con altre lingue. E anche se qualcuno ha messo il giusto valore per un parametro in una funzione membro di metodo o non significa necessariamente che non è rotto: Se un programma si aspetta un indirizzo IP, ma si passa un nome host, che ancora non funziona, anche se entrambi possono essere stringhe.

Quello che sto dicendo è: La mentalità di Python è intrinsecamente diversa. tipizzazione Anatra in pratica dice: Ehi, io non sono limitato a determinati tipi, ma per l'interfaccia, o il comportamento degli oggetti. Se un oggetto non agire come se fosse il tipo di oggetto che mi aspetto, non mi importa -. Basta andare per esso

Se si tenta di introdurre il controllo di tipo, si sono fondamentalmente limitando una delle caratteristiche più utili della lingua.

Detto questo, si ha realmente bisogno di entrare in test driven di sviluppo, o test di unità, almeno. Non c'è davvero nessuna scusa per non farlo con linguaggi dinamici - è semplicemente spostando il modo (tipo) gli errori vengono rilevati ad un altro passo nel processo di generazione, lontano dal tempo di compilazione di eseguire una suite di test più volte al giorno. Anche se questo sembra come sforzo aggiunto, sarà effettivamente ridurre il tempo speso per il debug e la fissazione del codice, in quanto è un modo intrinsecamente più potente per rilevare gli errori nel codice.

Ma abbastanza di che, sto già vagante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top