How to reference python package when filename contains a period
Solution 1
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.
Solution 2
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.
Solution 3
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).
Solution 4
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.
Solution 5
Like below
Assume dir structure is like this:
C:.
│ script.py
│
└───Parent
└───Child
├───1.1
│ main.py
│
└───1.2
**assume you want to import main.py in script.py **
your main.py looks like below
def my_function():
print("Hello from a function")
your script.py looks like below
from os import path
import importlib
from os.path import dirname
import sys
import importlib.util
def getPath():
# your logic to get to the path
return path.join(dirname(__file__),'Parent','Child','1.1','main.py')
file_path = getPath()
module_name = 'main'
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
#call functions like this
module.my_function()
Check out this gist
Comments
-
Alexander Bird over 2 years
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?
-
Cat Plus Plus over 14 years
load_source
is obsolete since at least 1.5. -
Cat Plus Plus over 14 yearsBad practice?
imp
is the mechanism behindimport
and__import__
. More flexibility, but requires more code. Nothing magical about it, though. -
shylent over 14 yearsAnd machine code is the mechanism behind everything. More flexibility and.. see where I'm going? :)
-
Cat Plus Plus over 14 yearsYou 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 - trac.edgewall.org/browser/trunk/trac/loader.py.
-
Edward Loper over 14 yearsTrue, 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))
-
shylent over 14 yearsMy 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.
-
Alexander Bird over 14 yearsFor 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. :)
-
haridsv about 14 yearsI think the important point is that this is an invalid module name as per python style guide: 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.
-
Alexander Bird about 11 yearsA module is a file. To quote the docs you referenced:
To support this, Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter. Such a file is called a module;
-
Trent almost 10 yearsDo you have a reference handy for this?
-
Gabriel Reid almost 10 yearsThe reference is the Python grammar spec (docs.python.org/2/reference/grammar.html). However, this actually only specifies what is allowed for the import statement -- as pointed out above in the accepted answer, it's technically possible to get around this by using the underlying import mechanisms.
-
Travis over 9 yearsTo try and make a case for this method of import, consider a naming convention for unit tests whereby code related to testing module x is kept in a file called 'x.test.py'. This works fine most of the time since the unit tests are not normally imported by other modules but if a developer wants to reuse the test for 'x' as the basis for additional testing (ie...maybe they want to test mutlithreaded use of x in a file called 'mtx.test.py') then they would find themselves needing to import 'x.test' which of course only works with the help of the 'imp' module.
-
Kevin over 9 yearsThis is formally deprecated as of 3.3. The correct way is to fiddle with the classes in
importlib.machinery
, which IMHO is way more trouble than it's worth. -
WattsInABox about 5 yearsI am working with a library where a version number has to be in the directory structure (not my choice). Since I have no choice, I need something like this so thanks for this answer!
-
Eric Burel almost 4 yearsWhat would be the best pattern for long names with multiple words? Naming a package, and thus a folder "awesome.project" will create issues, while "awesomeProject" seems an anti-pattern. Not sure I get this rule correctly: python.org/dev/peps/pep-0423/#id87
-
run_the_race over 2 yearsActually you can, see @SciTech Enthusiast answer