2008-12-16 8 views
2

Je crée une API simple qui crée des classes typées basées sur des données JSON qui ont un champ obligatoire 'type' défini dans celui-ci. Il utilise cette chaîne pour définir un nouveau type, ajouter les champs dans l'objet JSON, l'instancier, puis remplir les champs de l'instance.Liste toutes les classes qui existent actuellement

Ce que je veux être en mesure de faire est de permettre à ces types d'être éventuellement prédéfinis dans l'application qui utilise mon module. Cela permet d'ajouter des méthodes et d'autres attributs spécifiques aux applications introuvables dans l'objet JSON. J'aimerais que mon module vérifie si un type existe déjà, et si c'est le cas, utilisez-le au lieu de créer dynamiquement le type. Cela ajouterait encore des attributs à partir de l'objet JSON, mais ce serait le recyclage du type existant.

Mes données JSON est:

{ 
    "type": "Person", 
    "firstName": "John", 
    "lastName": "Smith", 
    "address": { 
     "streetAddress": "21 2nd Street", 
     "city": "New York", 
     "state": "NY", 
     "postalCode": 10021 
    }, 
    "phoneNumbers": [ 
     "212 555-1234", 
     "646 555-4567" 
    ] 
} 

Mon code à ce jour (en supposant json_object est un dict à ce stade):

if not json_object.has_key('type'): 
    raise TypeError('JSON stream is missing a "type" attribute.') 

##### THIS IS WHERE I WANT TO CHECK IF THE TYPE BY THAT NAME EXISTS ALREADY #### 
# create a type definition and add attributes to it 
definition = type(json_object['type'], (object,), {}) 
for key in json_object.keys(): 
    setattr(definition, key, None) 

# instantiate and populate a test object 
tester = definition() 
for key, value in json_object.iteritems(): 
    setattr(tester, key, value) 

Répondre

1

Vous pouvez utiliser dir() pour obtenir une liste de tous les noms de tous les objets dans l'environnement actuel, et vous pouvez utiliser globals() pour obtenir un dictionnaire mappant ces noms à leurs valeurs. Ainsi, pour obtenir seulement la liste des objets qui sont des classes, vous pouvez faire:

import types 
listOfClasses = [cls for cls in globals().values() if type(cls) == types.ClassType] 
0

Vous pouvez utiliser dir():

Python 2.5.2 (r252:60911, Oct 5 2008, 19:29:17) 
[GCC 4.3.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> dir() 
['__builtins__', '__doc__', '__name__'] 
>>> class Foo: 
...  pass 
... 
>>> dir() 
['Foo', '__builtins__', '__doc__', '__name__'] 
>>> type(eval('Foo')) 
<type 'classobj'> 
3

Si vous souhaitez réutiliser les types que vous avez créés précédemment, il est préférable de les mettre en cache vous-même:

json_types = {} 
def get_json_type(name): 
    try: 
    return json_types[name] 
    except KeyError: 
    json_types[name] = t = type(json_object['type'], (object,), {}) 
    # any further initialization of t here 
    return t 

definition = get_json_type(json_object['type']) 
tester = definition() 
# or: tester = get_json_type(json_object['type'])() 

Si vous voulez les avoir ajoutés à l'espace de noms de module, faire

json_types = globals() 

à la place.

Questions connexes