2010-07-25 5 views
10

È comune in Python continuare a testare i valori dei tipi quando si lavora in modalità OOP?È prassi comune testare i valori dei tipi in Python?

class Foo(): 
    def __init__(self,barObject): 
     self.bar = setBarObject(barObject) 

    def setBarObject(barObject); 
     if (isInstance(barObject,Bar): 
      self.bar = barObject 
     else: 
      # throw exception, log, etc. 

class Bar(): 
    pass 

O posso utilizzare un approccio più sciolto, come:

class Foo(): 
    def __init__(self,barObject): 
     self.bar = barObject 

class Bar(): 
    pass 

risposta

19

No, in realtà è schiacciante comune non per verificare i valori di tipo, come nel tuo secondo approccio. L'idea è che un client del tuo codice (ad esempio un altro programmatore che utilizza la tua classe) debba essere in grado di passare qualsiasi tipo di oggetto che abbia tutti i metodi o le proprietà appropriati. Se non si tratta di un'istanza di qualche particolare classe, va bene; il tuo codice non ha mai bisogno di sapere la differenza. Questo è chiamato anatra digitando, a causa del motto "Se cova come un'anatra e vola come un'anatra, potrebbe anche essere un'anatra" (beh, questo non è il vero adagio ma ho capito il senso di ciò penso)

Un luogo che si vede molto è nella libreria standard, con qualsiasi funzione che gestisca l'input o l'output del file. Invece di richiedere un oggetto effettivo file, prenderanno tutto ciò che implementa il metodo read() o readline() (a seconda della funzione) o write() per la scrittura. In effetti lo vedrai spesso nella documentazione, ad es. con tokenize.generate_tokens, che mi è capitato di essere alla ricerca di prima di oggi:

Il generatore generate_tokens() richiede un solo argomento, readline, che deve essere un oggetto richiamabile che fornisce la stessa interfaccia come il metodo di readline() built-in oggetti file (vedere la sezione File Objects). Ogni chiamata alla funzione dovrebbe restituire una riga di input come una stringa.

Questo consente di utilizzare un oggetto StringIO (come un file in memoria), o qualcosa di simile wackier una finestra di dialogo, al posto di un file reale.

Nel proprio codice, è sufficiente accedere a qualsiasi proprietà di un oggetto di cui si ha bisogno e, se si tratta del tipo di oggetto errato, una delle proprietà necessarie non sarà presente e genererà un'eccezione.

+4

Secondo. Vedi anche [EAFP] (http://docs.python.org/glossary.html#term-eafp): È più facile chiedere perdono che autorizzazione. –

+0

questo è molto interessante. Dopotutto, dovremmo goderci le caratteristiche dei pitoni invece di difenderci da loro. –

1

Penso che sia una buona pratica controllare l'input per il tipo. È ragionevole presumere che, se chiedessi a un utente di fornire un tipo di dati, potrebbero darti un altro, quindi dovresti codificarlo per difenderci da questo.

Tuttavia, sembra uno spreco di tempo (sia scrivere che eseguire il programma) per verificare il tipo di input che il programma genera indipendentemente dall'input. Come in un linguaggio fortemente tipizzato, la verifica del tipo non è importante per la difesa dall'errore del programmatore.

Quindi, in pratica, controlla l'input ma nient'altro in modo che il codice possa essere eseguito senza problemi e gli utenti non devono chiedersi perché hanno ottenuto un'eccezione piuttosto che un risultato.

+1

Probabilmente questo è un buon consiglio su altre lingue, ma non è una pratica comune in Python. Vedi la risposta di David sopra. –

+1

commento molto importante. continua a provare l'INPUT. la differenza tra errore del programmatore e errore dell'utente è importante. Grazie. –

+0

Non ne sono sicuro; Ho imparato Python dal MIT OCW e i professori del MIT hanno sempre parlato di "codifica difensiva", anche in python –

0

Se la tua alternativa al controllo del tipo è un altro contenente la gestione delle eccezioni, dovresti prendere in considerazione la digitazione anatra di un livello, il supporto di tutti gli oggetti con i metodi richiesti dall'input e il lavoro all'interno di una prova. Puoi quindi escludere (e tranne nel modo più specifico possibile) quello. Il risultato finale non sarebbe diverso da quello che hai lì, ma molto più versatile e Pythonic.

Tutto ciò che doveva essere detto sulla domanda reale, che si tratti di pratica comune o buona, penso che abbia avuto una risposta eccellente da parte di David.

0

Sono d'accordo con alcune delle risposte precedenti, in quanto generalmente non controllo mai il tipo da una funzione all'altra.

Tuttavia, come menzionato da qualcun altro, qualsiasi cosa accettata da un utente dovrebbe essere controllata, e per cose come questa uso espressioni regolari. Il bello dell'utilizzo di espressioni regolari per convalidare l'input dell'utente è che non solo è possibile verificare che i dati siano nel formato corretto, ma è possibile analizzare l'input in una forma più comoda, come una stringa in un dizionario.