2010-03-20 5 views
4

J'essaye d'archiver une tâche qui s'avère être un peu compliquée puisque je ne suis pas très bon en métaprogrammation Python.python metaprogramming

Je veux avoir un module locations avec la fonction get_location(name), qui renvoie une classe définie dans un dossier emplacements/dans le fichier avec le nom passé à la fonction. Le nom d'une classe est quelque chose comme NameLocation.

Donc, ma structure de dossier:

program.py 
locations/ 
    __init__.py 
    first.py 
    second.py 

program.py sera lissée avec avec:

from locations import get_location 
location = get_location('first') 

et l'emplacement est une classe définie dans smth first.py comme ceci:

from locations import Location # base class for all locations, defined in __init__ (?) 
class FirstLocation(Location): 
    pass 

etc.

Ok, j'ai essayé beaucoup de importer et getattribute déclarations mais maintenant je m'ennuie et abandonner. Comment archiver un tel comportement?


Je ne sais pas pourquoi, mais ce code

def get_location(name): 
    module = __import__(__name__ + '.' + name) 
    #return getattr(module, titlecase(name) + 'Location') 
    return module 

retours

>>> locations.get_location('first') 
<module 'locations' from 'locations/__init__.py'> 

le module déstinations! Pourquoi?!

+5

Cette idée est douloureuse juste pour lire. Êtes-vous vraiment sûr de vouloir suivre cette route? –

+0

Je dois être capable de faire quelque chose comme dans mon exemple program.py. S'il y a un autre itinéraire, faites le moi savoir! :) Désolé pour la lecture douloureuse, mon anglais n'est pas très bon. –

+0

Ce n'est pas tellement l'anglais. C'est l'idée. SVP expliquez * pourquoi * vous en avez besoin. Aussi que signifie "smth"? Veuillez utiliser les guillemets "\' 'autour des variables Python avec' _'. –

Répondre

6

Vous avez besoin de __import__ le module; après cela, obtenir un attr de ce n'est pas difficile.

import sys 

def get_location(name): 
    fullpath = 'locations.' + name 
    package = __import__(fullpath) 
    module = sys.modules[fullpath] 
    return getattr(module, name.title() + 'Location') 

Modifier: __import__ retourne le paquet, vous avez donc besoin d'un plus getattr, voir the docs (et lire toute la section attentivement - « ce que je dis pas ce que je fais » ;-).

+0

(où il n'y avait pas de méthode titlecase donc j'ai utilisé l'extrait de quelqu'un) J'ai AttributeError: objet 'module' n'a pas d'attribut 'FirstLocation' –

+0

s'il vous plaît regarder ma question, j'ai ajouté info (douloureuse) –

+0

Ah, je vois , éditer pour réparer. –

1

Je pense que vous cherchez:

location = __import__('first') 
+0

ImportError: aucun module nommé en premier, lorsque je retourne l'emplacement de get_location avec votre code –

+1

Eh bien, l'adapter à tout ce que vous essayez de faire, mais c'est comme ça que vous importez un module utilisant une chaîne comme nom. – MikeyB