2009-08-24 13 views
14

ho bisogno per determinare se una data variabile Python è un esempio di tipo nativo: str, int, float, bool, list, dict e così via. C'è un modo elegante per farlo?Determinare se la variabile Python è un'istanza di un tipo built-in

O è questo l'unico modo:

if myvar in (str, int, float, bool): 
    # do something 
+5

Che cosa si intende per tipo "nativo"? Intendi costruzione? Perché hai bisogno di saperlo? Python non è C++ o Java, quindi non c'è distinzione tra tipi "semplici" o "nativi". Cosa stai cercando di fare? –

+0

Sì, suppongo che intenda i tipi "incorporati". Ho bisogno di tale rappresentazione di un oggetto, che ho potuto usarlo in JSON serializzazione. simplejson "gestisce" solo questi tipi. In altri casi (quando l'oggetto è istanze di classi "fatte in casa") ho bisogno di creare oggetti dict. –

+1

Sapete che simplejson ha qualcosa chiamato "decodifica oggetto" e "codifica oggetto"? –

risposta

12

Il modo migliore per raggiungere questo obiettivo è quello di raccogliere i tipi in un elenco di tuple chiamato primitiveTypes e:

if isinstance(myvar, primitiveTypes): ... 

Il types module contiene collezioni di tutti i tipi importanti che possono contribuire a creare l'elenco/tupla .

Works since Python 2.2

+0

thx. è forse più elegante di quello che ho scritto inizialmente. –

+2

l'utilizzo di tipi da "tipi" non è diverso dall'uso diretto dei nomi più diretti (int, str, float, ...)! – u0b34a0f6ae

+0

Sì, è così che funzionano i tipi. Ma rende le tue intenzioni più pulite e se usi i set predefiniti (StringTypes), ottieni un'ulteriore portabilità tra le versioni di Python. –

1

costruito in funzione di tipo può essere utile:

>>> a = 5 
>>> type(a) 
<type 'int'> 
2

Che cosa è un "tipo nativo" in Python? Si prega di non basare il proprio codice sui tipi, utilizzare Duck Typing.

+0

Grazie, ci penserò due volte prima di farlo =) –

7

Non che io sappia perché vorresti farlo, dato che non ci sono tipi "semplici" in Python, sono tutti oggetti. Ma questo funziona:

type(theobject).__name__ in dir(__builtins__) 

Ma elencare esplicitamente i tipi è probabilmente migliore in quanto è più chiaro. O ancora meglio: cambiare l'applicazione in modo da non aver bisogno di sapere la differenza.

Aggiornamento: il problema che deve essere risolto è come creare un serializzatore per gli oggetti, anche quelli integrati. Il modo migliore per farlo non è creare un serializzatore Phat che tratti i builtin in modo diverso, ma cercare i serializzatori in base al tipo.

Qualcosa di simile a questo:

def IntSerializer(theint): 
    return str(theint) 

def StringSerializer(thestring): 
    return repr(thestring) 

def MyOwnSerializer(value): 
    return "whatever" 

serializers = { 
    int: IntSerializer, 
    str: StringSerializer, 
    mymodel.myclass: MyOwnSerializer, 
} 

def serialize(ob): 
    try: 
     return ob.serialize() #For objects that know they need to be serialized 
    except AttributeError: 
     # Look up the serializer amongst the serializer based on type. 
     # Default to using "repr" (works for most builtins). 
     return serializers.get(type(ob), repr)(ob) 

In questo modo è possibile aggiungere facilmente nuovi serializzatori, e il codice è facile da mantenere e chiaro, come ogni tipo ha la propria serializzatore. Si noti come il fatto che alcuni tipi siano incorporati è diventato completamente irrilevante. :)

+4

funziona, ma non si dovrebbe usare:/ – NicDumZ

+0

+1 "Cambiare l'applicazione quindi non hai bisogno di sapere la differenza. " Alcuni (estremamente rari) tempi è necessario sapere, ma molto probabilmente non lo è. – voyager

7

È sembrano essere interessati ad assicurare la simplejson gestirà i tipi di. Questo è fatto banalmente da

try: 
    json.dumps(object) 
except TypeError: 
    print "Can't convert", object 

Quale è più affidabile di cercare di indovinare quali tipi gestisce l'implementazione JSON.

+0

questo è più pythonic perche 'se l'oggetto può essere scaricato (diciamo forse simplejson aggiunge altro supporto) allora verrà usato prima, e poi nell'eccezione dovresti chiamare la tua funzionalità catchall. +1 –

0

costruzione al largo della risposta di S. Lott si dovrebbe avere qualcosa di simile:


from simplejson import JSONEncoder 

class JSONEncodeAll(JSONEncoder): 
    def default(self, obj): 
    try: 
     return JSONEncoder.default(self, obj) 
    except TypeError: 
     ## optionally 
     # try: 
     # # you'd have to add this per object, but if an object wants to do something 
     # # special then it can do whatever it wants 
     # return obj.__json__() 
     # except AttributeError: 
     ## 

     # ...do whatever you are doing now... 
     # (which should be creating an object simplejson understands) 

da usare:


>>> json = JSONEncodeAll() 

>>> json.encode(myObject) 
# whatever myObject looks like when it passes through your serialization code 

queste chiamate utilizzeranno la classe speciale e se simplejson può prendere cura del oggetto lo farà.Altrimenti verrà attivata la funzionalità Catchall e probabilmente (a seconda se si utilizza la parte facoltativa) un oggetto può definire la propria serializzazione

5

Questa è una vecchia domanda ma sembra che nessuna delle risposte in realtà risponda alla domanda specifica: "(How-to) Determina se la variabile Python è un'istanza di un tipo built-in ". Si noti che non è "[...] di una specifica /data tipo built-in", ma di un .

Il modo corretto per determinare se un dato oggetto è un'istanza di uno s-in caratteri/classe è di controllare se il tipo dell'oggetto sembra essere definito nel modulo __builtin__.

def is_builtin_class_instance(obj): 
    return obj.__class__.__module__ == '__builtin__' 

Attenzione: se obj è una classe e non un caso, non importa se questa classe è built-in o no, vero saranno restituiti dal momento che una classe è anche un oggetto, un'istanza di type (cioè AnyClass.__class__ è type).

1

è possibile accedere a tutti questi tipi da types modulo:

`builtin_types = [ i for i in types.__dict__.values() if isinstance(i, type)]` 

come promemoria, modulo di importazione types primo

def isBuiltinTypes(var): 
    return type(var) in [i for i in types.__dict__.values() if isinstance(i, type)] and not isinstance(var, types.InstanceType) 
0

Per me la soluzione migliore è:

allowed_modules = set(['numpy']) 
def isprimitive(value): 
    return not hasattr(value, '__dict__') or \ 
    value.__class__.__module__ in allowed_modules 

Questa correzione quando value è un modulo e value.__class__.__module__ == '__builtin__' avrà esito negativo.

Problemi correlati