2010-11-20 14 views
20

Ho una base di codice che utilizza StringType e NoneType (types module) nella base di codice python2.x. Nel porting su Python3, i test non sono riusciti poiché il modulo types in Python3.x non ha i due tipi sopra menzionati.StringType e NoneType in python3.x

Ho risolto il problema sostituendolo con "str" ​​e "None" rispettivamente. Mi stavo chiedendo se c'è un altro (giusto) modo di farlo. Quello che sto facendo attualmente sembra decisamente funzionare, ma sono dubbioso.

Devo attenermi all'approccio che ho seguito o c'è qualcosa di sbagliato in ciò che ho fatto? Se sì, come lo correggo?

risposta

19

Il controllo di Nessuno viene in genere eseguito chiamando obj is None, mentre il controllo della stringa di solito è isinstance(obj, str). In Python 2.x per rilevare sia string che unicode, è possibile utilizzare isinstance(obj, basestring).

Se si utilizza 2to3, è abbastanza, ma se avete bisogno di avere unico pezzo di codice funzionante sia in PY2 e PY3, si può finire con qualcosa di simile:

try: 
    return isinstance(obj, basestring) 
except NameError: 
    return isinstance(obj, str) 
+2

Hai ragione, ma è generalmente consigliato per rendere il codice che passerà attraverso '2to3 'correttamente piuttosto che fare un sacco di codice per gestire tutte le situazioni. Se usi semplicemente 'isinstance (obj, basestring)', '2to3' lo cambierà in' isinstance (obj, str) '. –

+0

Ah, ok, non avevo idea di 2to3 - Ho appena scritto una piccola libreria che doveva funzionare in entrambi. Risolverò la mia risposta. –

4

Ove possibile lo consiglio che si evitino i valori in types se i loro valori sono evidenti; quindi per qualcosa come legare un metodo a un oggetto, utilizzare types.MethodType, ma per types.StringTypes utilizzare (str, unicode) o piuttosto basestring.

Per questa situazione, vorrei fare questo:

  • Usa obj is None o obj is not None piuttosto che isinstance(obj, NoneType) o not isinstance(obj, NoneType).
  • Usa isinstance(obj, basestring) piuttosto che isinstance(obj, StringTypes)
  • Usa isinstance(obj, str) piuttosto che isinstance(obj, StringType)

Poi, quando si è bisogno di distribuire per Python 3, utilizzare 2to3. Quindi il tuo basestring diventerà str e il resto continuerà a funzionare come prima.

(Inoltre, tenete a mente questo, in particolare, la differenza tra StringType e StringTypes:

types.UnicodeType == unicode 
types.StringType == str 
types.StringTypes == (str, unicode) 

)