2010-09-07 14 views
0

Je le code suivant:usine d'objet qui génère un objet ou d'une liste d'objets

def f(cls, value): 
    # cls is a class 
    # value is a string value 
    if cls == str: 
    pass # value is already the right type 
    elif cls == int: 
    value = int(value) 
    elif cls == C1: 
    value = C1(value) 
    elif cls == C2: 
    value = C2(value) 
    elif cls == C3 
    # in this case, we convert the string into a list of objects of class C3 
    value = C3.parse(value) 
    else 
    raise UnknownClass(repr(cls)) 
    return value 

De toute évidence, je suis en train de le remplacer par quelque chose comme:

def f(cls, value) 
    return cls(value) 

Malheureusement, dans certains cas (si cls == C3), l'analyse de l'entrée aboutit à une liste d'objets de cette classe, plutôt qu'à un seul objet. Quelle est la bonne façon de gérer cela? J'ai accès à toutes les classes.

Répondre

2

Si la plupart des cas sont mieux gérées en appelant cls, et quelques-uns sont mieux gérées sinon, le plus simple est de choisir ce dernier:

themap = {C3: C3.parse} 
for C in (str, C1, C2): 
    themap[C] = C 

def f(cls, value): 
    wot = themap.get(cls) 
    if wot is None: 
     raise UnknownClass(repr(cls)) 
    return wot(value) 

Notez que l'appel str sur une chaîne est un noop assez rapide, il est donc généralement à éviter absolument le « singulariser » de ce cas spécifique en faveur de la simplicité du code.

+0

Il n'y a aucun moyen de renvoyer une liste de X au lieu de simplement X de X(), je suppose? – max

+0

@max, quand vous écrivez une 'classe X', vous pouvez remplacer 'X .__ new__' pour retourner ce que vous voulez (si ce n'est pas une instance' X',' X .__ init__' n'est pas appelé) - of Bien sûr, cela peut avoir de sérieux inconvénients, ce qui rend difficile par exemple d'avoir une seule instance de 'X' (alors comment obtenez-vous les instances à mettre dans cette liste ...?) - pas impossible, mais extrêmement gênant. 'classmethod' est généralement un meilleur moyen d'encadrer les constructeurs" alternatifs ". –

0

Cela dépend de ce que vous feriez avec la liste. Ceci est la façon la plus simple:

obj = cls (valeur)

si le type (obj) == Liste:

handle_list (obj)

retour obj

+0

Il est recommandé d'utiliser la méthode intégrée isinstance au lieu d'utiliser le type! – shahjapan