Sta cambiando il tipo di una variabile partway attraverso una procedura in uno stile bad tipizzato in modo dinamico?

7

In Python (e occasionalmente in PHP) dove le variabili non hanno tipi fissi, eseguirò frequentemente 'tipo trasformazioni' su una variabile in modo parziale attraverso la logica del mio codice. Non parlo (necessariamente) di cast semplici, ma di funzioni che cambiano il tipo di una variabile, mentre lasciano sostanzialmente il medesimo valore o dati.

Ad esempio, potrei scrivere un codice come questo quando faccio una richiesta web, usando la variabile response per memorizzare un oggetto addurlinfo, poi il contenuto stringa di quell'oggetto e il dizionario restituito analizzando la stringa come JSON:

response = urlopen(some_url)
assert response.info().type == 'application/json'

response = response.read()
logger.debug('Received following JSON response: ' + response)

response = json.loads(response)
do_something(response)

(Ok, è un esempio un po 'forzato, ma penso che dimostri l'idea). La mia sensazione è che questo è meglio dell'uso di tre nomi di variabili separati perché a) trasmette che la variabile response contiene fondamentalmente la stessa informazione, solo 'trasformata' in un tipo diverso, e b) trasmette che gli oggetti precedenti non sono ' Ci vorrà ancora più in basso nella funzione, poiché riassegnando la loro variabile li ho resi non disponibili al codice successivo.

Il compromesso, immagino, è che il lettore potrebbe confondersi sul tipo di variabile in un dato momento.

È questo cattivo stile e dovrei usare tre diverse variabili nell'esempio sopra invece di riassegnare a uno? Inoltre, questa pratica standard è in lingue digitate dinamicamente o no? Non ho visto abbastanza codice di altre persone da sapere.

    
posta Mark Amery 17.02.2013 - 12:40
fonte

3 risposte

8

Esco su un ramo e dico: No, questa è una pessima idea.

È solo un caso speciale di riutilizzare una variabile, che è una cattiva idea - principalmente perché rende difficile capire cosa una variabile contiene in un dato punto nel flusso del programma. Vedi per es. Devo riutilizzare le variabili?

Informazioni sui punti: i punti che hai sollevato sono validi, è solo che riutilizzare la variabile non è una buona soluzione: -).

a) it conveys that the response variable contains basically the same information, just 'transformed' into a different type

Fornire queste informazioni è un'idea buona . Tuttavia, non farlo usando la stessa variabile, perché in questo modo oscuri il fatto che sia stata trasformata l'informazione. Piuttosto, usa nomi con un pre / postfix comune. Nel tuo esempio:

rawResponse = urlopen(some_url)
[...]    
jsonResponse = response.read()
[...]    
responseData = json.loads(response)
[...]

Questo rende chiaro che le variabili sono strettamente correlate, ma anche che non contengono gli stessi dati.

b) it conveys that the earlier objects aren't going to be needed any further down the function, since by reassigning over their variable I've made them unavailable to later code.

Ancora una volta, comunicare questo "non più necessario" è buono, ma non farlo riutilizzando la variabile: l'assegnazione del riutilizzo sarà solitamente difficile da vedere, quindi confonderai solo il lettore.

Piuttosto, se una variabile vive a lungo dopo il suo ultimo utilizzo, è un'indicazione che il metodo / funzione è troppo lungo. Dividi la parte con le variabili di breve durata in una sotto funzione; questo rende il codice più facile da leggere e limita la durata della variabile.

Nota: di solito vado anche oltre, non riusando le variabili, e cerco anche di assegnare un valore solo una volta (cioè non cambiare mai il valore, renderlo immutabile). Questa è un'idea principalmente dai linguaggi funzionali, ma ho scoperto che può rendere il codice molto più chiaro. Ovviamente, in linguaggi non funzionali, a volte è necessario modificare una variabile (ovvio esempio essendo una variabile di ciclo), ma una volta che inizi a guardare, vedrai che nella maggior parte dei casi una variabile "fresca" rende più leggibile e meno codice soggetto a bug.

    
risposta data 20.02.2013 - 12:17
fonte
6

So che stai leggendo da un URL nel tuo esempio, ma se hai provato la stessa cosa con un file non saresti in grado di chiudere il file perché la risposta non sta più puntando al file, ora sta tenendo un pungolo recuperato dal file.

Questo è il grande pericolo, potresti dimenticare quale valore tiene perché cambia durante la vita del programma o del modulo. Sarà confuso per qualcuno che legge il tuo codice perché non saprà mai quale tipo di valore ha in mano.

Questi sono gli insetti divertenti che provano e schiacciano.

    
risposta data 17.02.2013 - 13:42
fonte
4

In generale, direi di sì, è un cattivo stile, ma ci sono casi in cui è necessario e utile riutilizzare una variabile; Vorrei solo raccomandare di evitare un uso casuale e pigro.

Il problema con il tuo esempio non è dovuto alla digitazione dinamica, ma perché usi la stessa variabile per riferirti a tre cose diverse. Questo codice è meno chiaro per me perché quando lo leggo, devo pensare molto più difficile a capire a cosa si riferisce response .

Si potrebbe fare qualcosa di altrettanto sgradevole in un linguaggio tipizzato in modo statico come Java (con la restrizione che le diverse cose siano correlate attraverso una gerarchia di tipi). Il punto chiave è che l'utilizzo di una singola variabile per puntare a oggetti diversi può creare confusione, indipendentemente dal tipo di sistema.

    
risposta data 17.02.2013 - 14:00
fonte

Leggi altre domande sui tag