2009-08-24 5 views
14

je dois déterminer si une variable Python donnée est une instance de type natif: str, int, float, bool, list, dict et ainsi de suite. Y a-t-il un moyen élégant de le faire?Déterminer si la variable Python est une instance d'un type intégré

Ou est-ce la seule façon:

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

Qu'entendez-vous par type «natif»? Voulez-vous dire builtin? Pourquoi avez-vous besoin de savoir cela? Python n'est pas C++ ou Java, donc il n'y a pas de distinction entre les types "simples" ou "natifs". Qu'essayez-vous de faire? –

+0

Oui, je suppose que je veux dire "builtin" types. J'ai besoin d'une telle représentation d'un objet, que je pourrais utiliser dans la sérialisation JSON. Simplejson "manipule" uniquement ces types. Dans d'autres cas (lorsque des objets sont des classes "maison"), j'ai besoin de faire des objets dict. –

+1

Vous savez que simplejson a quelque chose appelé "décodage d'objet" et "encodage d'objet"? –

Répondre

12

La meilleure façon d'y parvenir est de collecter les types dans une liste de tuple appelé primitiveTypes et:

if isinstance(myvar, primitiveTypes): ... 

Le types module contient des collections de tous les types importants qui peuvent aider à construire la liste/tuple .

Works since Python 2.2

+0

thx. c'est peut-être plus élégant que ce que j'ai écrit initialement. –

+2

en utilisant les types de 'types' n'est pas différent que d'utiliser les noms les plus simples (int, str, float, ...) directement! – u0b34a0f6ae

+0

Oui, c'est comme ça que ça fonctionne. Mais cela rend votre intention plus propre et si vous utilisez les ensembles prédéfinis (StringTypes), vous obtenez une portabilité supplémentaire entre les versions de Python. –

1

Construit en fonction de type peut être utile:

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

Qu'est-ce qu'un "type natif" en Python? Veuillez ne pas baser votre code sur les types, utilisez Duck Typing.

+0

Merci, je vais réfléchir à deux fois avant de le faire =) –

7

Pas que je sache pourquoi vous voudriez le faire, car il n'y a pas de types "simples" en Python, ce sont tous des objets. Mais cela fonctionne:

type(theobject).__name__ in dir(__builtins__) 

Mais énumérer explicitement les types est probablement meilleur car il est plus clair. Ou encore mieux: Changer l'application pour ne pas avoir besoin de connaître la différence. Mise à jour: Le problème à résoudre est de savoir comment créer un sérialiseur pour les objets, même ceux qui sont intégrés. La meilleure façon de le faire est de ne pas faire un grand sérialiseur phat qui traite différemment les builtins, mais de rechercher des sérialiseurs basés sur le type.

Quelque chose comme ceci:

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) 

De cette façon, vous pouvez facilement ajouter de nouveaux serializers, et le code est facile à entretenir et claire, que chaque type a son propre sérialiseur. Remarquez comment le fait que certains types sont intégrés est complètement hors de propos. :)

+4

cela fonctionne, mais vous ne devriez pas l'utiliser:/ – NicDumZ

+0

+1 "Modification de l'application donc tu n'as pas besoin de connaître la différence. " Quelques fois (extrêmement rare) est nécessaire de savoir, mais le plus probablement ne l'est pas. – voyager

7

Vous semblez être intéressé à assurer la simplejson se chargera de vos types. Ceci est fait trivialement par

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

Ce qui est plus fiable que d'essayer de deviner quels types votre implémentation JSON gère.

+0

c'est plus pythonique parce que si l'objet peut être jeté (disons que simplejson ajoute plus de support) alors il sera utilisé d'abord, et ensuite dans l'exception vous devriez appeler votre fonctionnalité catchall. +1 –

0

construction hors de la réponse de S. Lott, vous devriez avoir quelque chose comme ceci:


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) 

à utiliser:


>>> json = JSONEncodeAll() 

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

ces appels utiliseront votre classe spéciale et si simplejson peut prendre soin de la objet, il le fera.

5

Il s'agit d'une vieille question, mais il semble qu'aucune des réponses ne réponde vraiment à la question spécifique: "((La fonction de chariots est activée. How-to) Déterminer si la variable Python est une instance d'un type prédéfini ". Notez que ce n'est pas "[...] d'un spécifique/donné de type intégré" mais de un.

La bonne façon de déterminer si un objet donné est une instance d'une Buil-in Type/classe est de vérifier si le type de l'objet se trouve être définie dans le module __builtin__.

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

Attention: si obj est une classe et non une instance, peu importe si cette classe est intégrée ou non, True sera retourné depuis une classe est aussi un objet, une instance de type (c.-à-AnyClass.__class__ est type).

1

vous pouvez accéder à tous ces types par le module types:

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

comme un rappel, le module d'importation types premier

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

Pour moi, la meilleure option est:

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

Cette correction lorsque la valeur est un module et value.__class__.__module__ == '__builtin__' échouera.

Questions connexes