views:

396

answers:

2

I'm trying to archive a task which turns out to be a bit complicated since I'm not very good at Python metaprogramming.

I want to have a module locations with function get_location(name), which returns a class defined in a folder locations/ in the file with the name passed to function. Name of a class is something like NameLocation.

So, my folder structure:

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

program.py will be smth with with:

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

and the location is a class defined in first.py smth like this:

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

etc.

Okay, I've tried a lot of import and getattribute statements but now I'm bored and surrender. How to archive such behaviour?


I don't know why, but this code

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

returns

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

the locations module! why?!

A: 

I think you're looking for:

location = __import__('first')
MikeyB
ImportError: No module named first, when I'm returning the location from get_location with your code
valya
Well, adapt it to whatever the heck you're trying to do, but that's how you import a module using a string as the name.
MikeyB
+2  A: 

You do need to __import__ the module; after that, getting an attr from it is not hard.

import sys

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

Edit: __import__ returns the package, so you need one more getattr, see the docs (and read all the section carefully -- "do as I say not as I do";-).

Alex Martelli
(where was no titlecase method so I've used someone's snippet) I got AttributeError: 'module' object has no attribute 'FirstLocation'
valya
please look at my question, I've added additional (painful) info
valya
Ah, I see, editing to fix.
Alex Martelli
brilliant!!! thanks. (again, str has no titlecase method, or i don't know about it)
valya
It's just `.title()`, not `.titlecase()` -- editing to fix, sorry.
Alex Martelli