tags:

views:

136

answers:

3

I'm working on a Django project. Let's call it myproject. Now my code is littered with myproject.folder.file.function. Is there anyway I can remove the need to prefix all my imports and such with myproject.? What if I want to rename my project later? It kind of annoys me that I need to prefix stuff like that when the very file I'm importing it from is inside that same project. Shouldn't be necessary.

+5  A: 

from myproject.folder import file (horrible name, btw, trampling over the builtin type file, but that's another rant;-), then use file.function -- if file (gotta hate that module name;-) is still too long for you, add e.g. as fi to the from statement, and use fi.function. If you want to rename myproject to myhorror, you only need to touch the from statements addressing it (you could use relative imports, but those would break 2.5 compatibility and therefore ban you from App Engine for now -- too high a price to pay for minor convenience, for me at least;-).

Edit: if just about every file needs some given supporting module, that's a powerful reason for making sure that supporting module lives in a directory (or zipfile) that's on sys.path (it's probably worth doing even if, say, only 30% of the files need that supporting module!-).

Alex Martelli
+1 for `myproject` to `myhorror`, but I think the OP was just saying `myproject.folder_in_myproject.specific_file_in_my_project.function_I_want` rather than actually having a `file.py` file he/she was importing.
Chris Lutz
Actaully, the OP has a nice picture of himself. Why did I say he/she?
Chris Lutz
Chris is right. I don't have any files named `file.py`. I know about the `from` style imports, but this isn't a project-wide solution. I still have to have `myproject` at the top of every single file. And I don't know if this will work in Django urlpatterns? It's not really an import statement you just write it as a string, and then django dynamically imports it later.
Mark
@Mark, if "every single file" needs some supporting module, that's a **powerful** reason for making sure that supporting module lives in a directory (or zipfile) that's on `sys.path` (I'd surely do that even if it was "just" 30% or so of files -- for **every** file, I'd jump through rings of fire to do it!!!-).
Alex Martelli
@Alex: Write that as an answer and I'll give you the checkmark. That's the solution I was looking for but was too stupid to realize it :p
Mark
@Mark, edited this answer to include the consideration in the above comment, as per your suggestion!
Alex Martelli
Putting something like this in `settings.py` works nicely: `sys.path.append(os.path.dirname(__file__))`
Mark
+2  A: 
import x as y
import x.y as z
from x import y as z

The "as" allows you to give your own name to an imported module. For example, import os as System would allow you to call the components of the os module like so:

System.path.abspath('bla')

For more information about imports, read: Importing Python Modules

Chris
+1  A: 

If you don't mind clobbering file:

from myproject.folder import file

If you want to make file something shorter:

import myproject.folder.file as f

You could create your own import statement if you were feeling really fancy:

head = 'myproject.folder.'
def my_import(name,*args,**kwargs):
   try:
       return __import__(name, *args, **kwargs)
   except ImportError: 
       return __import__(head+name, *args, **kwargs)

file = my_import('file')

You can also be outright evil, and hack the builtin python import statement:

head = 'myproject.folder.'

_import = __import__ # don't clobber __import__ yet

def my_import(name,*args,**kwargs):
   try: 
       return _import(name,*args,**kwargs)
   except ImportError:
       return _import(head+name, *args, **kwargs)

__builtins__.__import__ = my_import # God just killed a maintainer

# elsewhere, after the above abomination has run:
import file # I hope you are happy.

Actually, I'm exaggerating the evil of clobbering built-in functions. It's not that bad. But it is a little bit hairy.

wisty
It actually *does* sound incredibly evil. +1 for effort, but I would never take this approach.
Mark