views:

305

answers:

5

I am using django and I have a file named models.admin.py and I want to do the following idea in models.py:

from "models.admin" import *

however, I get a syntax error for having double quotes. But if I just do

from models.admin import *

then I get "ImportError: No module named admin"

Is there any way to import from a python file (that has a period in its name)?

+2  A: 

The file is called models/admin.py. (Source)

That is, it should be called admin.py in a directory called models.

Then you can import using from models.admin import *, assuming that it is in your Python path.

Mark Byers
A: 

No, you can't import a python file as a module if its name contains a period (or a question mark, or exclamation mark, etc). A python module's name (not including the .py) must be a valid python name (ie can be used as a variable name).

gab
A: 

You are not referencing files in the import statement, you are referencing modules and packages.

Please read the docs, they are very clear on that matter.

Anyway, since you are using django, the usual approach won't work. If you want to keep models in separate files, rather than in models.py, you have to take extra steps, outlined, for example, here.

Edit:
Well, I don't really know what the questioneer means when he mentions admin and whether or not it is related to the admin interface of django. My points still stand.

shylent
+1  A: 

If you really want to, you can import a module with an unusual filename (e.g., a filename containing a '.' before the '.py') using the imp module:

>>> import imp
>>> a_b = imp.load_source('a.b', 'a.b.py')
>>> a_b.x
"I was defined in a.b.py!"

However, that's generally a bad idea. It's more likely that you're trying to use packages, in which case you should create a directory named "a", containing a file named "b.py"; and then "import a.b" will load a/b.py.

Edward Loper
`load_source` is obsolete since at least 1.5.
PiotrLegnica
True, though the non-obsolete way of doing it is quite a bit wordier: a_b = imp.load_module('a.b', open('a.b.py'), os.path.abspath('a.b.py'), ('.py', 'r', imp.PY_SOURCE))
Edward Loper
+6  A: 

Actually, you can import a module with an invalid name. But you'll need to use imp for that, e.g. assuming file is named models.admin.py, you could do

import imp
with open('models.admin.py', 'rb') as fp:
    models_admin = imp.load_module(
        'models_admin', fp, 'models.admin.py',
        ('.py', 'rb', imp.PY_SOURCE)
    )

But read the docs on imp.find_module and imp.load_module before you start using it.

PiotrLegnica
Woah, this *reeks* of bad practice. Even though it is possible to do (to be honest, I didn't know this technique), this is one of those things, that are "cool" to know, but should never be used. Not in production. Not anywhere.
shylent
Bad practice? `imp` is the mechanism behind `import` and `__import__`. More flexibility, but requires more code. Nothing magical about it, though.
PiotrLegnica
And machine code is the mechanism behind everything. More flexibility and.. see where I'm going? :)
shylent
You obviously need to think twice if you really need to use it, but I don't see how using it is terribly wrong. ;) And it is used in production - see e.g. Trac - http://trac.edgewall.org/browser/trunk/trac/loader.py.
PiotrLegnica
My main point is, that, perhaps it is *not* terribly wrong to use this (ok, my subjective opinion is that it *is* terribly wrong, but away with that), but it is certainly not particularly right to advise it to someone who doesn't quite grasp the concept of modules and packages yet.
shylent
For the record, I never actually named my file that the instant I realized this was going to be complicated. But after Googling out of curiosity and failing to find the answer, I decided that I wanted both the answer (import imp) and the voice of accepted practice (don't use it) to be archived for future Googlers. :)
Thr4wn
I think the important point is that this is an invalid module name as per python style guide: http://www.python.org/dev/peps/pep-0008/. However, in OP's case, if module name can't be changed, this solution seems like it is reasonable, as it uses well documented interface. In other words, it is unlikely for a future python minor release to change this behavor. If the solution involved undocumented features, it is a different matter and I would have agreed with shylent.
haridsv