In python, how to import filename starts with a number
Asked Answered
S

4

131

Basically there is a file called 8puzzle.py and I want to import the file into another file (in the same folder and I cannot change the file name as the file is provided). Is there anyway to do this in Python? I tried usual way from 8puzzle import *, it gives me an error.

Error is:

>>> import 8puzzle
  File "<input>", line 1
    import 8puzzle
           ^
SyntaxError: invalid syntax
>>> 
Synod answered 1/2, 2012 at 2:51 Comment(6)
Why do people say "it gives me [an] error" and then not post what the error is?Gerbil
@JohnZwinck It's a syntax error. I'm guessing because "8puzzle" isn't a valid identifier (it starts with a number), and the syntax for the import statement expects a Python identifier there. Which would make the answer "No, you can't. Rename the module to something that starts with a letter or an underscore."Chuvash
John made the good point, I will keep in mind. And thanks Abhijeet add the error message for me. Thanks.Synod
Rename 8puzzle.py to puzzle8.py and use import puzzle8.Cowbind
See also #6812402Sedlik
For people wondering: one use case is having filenames start with the date to structure a directory of one-off scripts (20190911_test_foo.py, 20190911_test_bar.py, 20190911_some_class_used_for_foo_and_bar).Polson
D
150

You could do

puzzle = __import__('8puzzle')

Very interesting problem. I'll remember not to name anything with a number.

If you'd like to import * -- you should check out this question and answer.

12 years later...

See answer below (use importlib.import_module from Python 3.1) for interoperability and understandability.

https://docs.python.org/3/library/importlib.html#importlib.import_module

This provides an implementation of import which is portable to any Python interpreter. This also provides an implementation which is easier to comprehend than one implemented in a programming language other than Python.

....

The import_module() function acts as a simplifying wrapper around importlib.__import__(). This means all semantics of the function are derived from importlib.__import__(). The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg.mod), while __import__() returns the top-level package or module (e.g. pkg).

Dryclean answered 1/2, 2012 at 2:59 Comment(5)
works great! thanks. yeah, I would not name it start with a number, but it is a course assignment handout file, so I cannot change the name. But it seems doesn't matter though as we already got the solution for it. Thanks again.Synod
Help save the world, or at least your classmates. If you get handed an impossible import, bring it to the instructor's attention. Yeah, sometimes they hate being wrong, but if you are having this problem, so is everyone else and although this answer works, it is not the right solution (unless the class is "Obfuscated Python 101").Cheddar
A better way (with python 2.7 at least) is to use the 'importlib' module : puzzle = importlib.import_module('8puzzle')Acoustics
There is actually a good use case for this - as part of compiling/productionizing process, concatenating python modules together is easiest if they are named in lexigraphical form (generally it doesn't matter, but constants and imports at the top, 'if name' at bottom, so a few modules that start with '0' can be useful.) Also useful in debugging such an unusual directory layout, when combined with inotify or watch, something like: watch -n .1 'cat * | python', which would load your python app every tenth of a second (or at least as fast as possible), or: cat $(find . -name "*.py") | pythonOligosaccharide
Late to the party, but another use case is importing from Alembic migrations, since they all start with random hashesTisdale
L
51

The above answers are correct, but as for now, the recommended way is to use import_module function:

importlib.import_module(name, package=None)
Import a module. The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).

The import_module() function acts as a simplifying wrapper around importlib.__import__(). This means all semantics of the function are derived from importlib.__import__(). The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg.mod), while __import__() returns the top-level package or module (e.g. pkg).

If you are dynamically importing a module that was created since the interpreter began execution (e.g., created a Python source file), you may need to call invalidate_caches() in order for the new module to be noticed by the import system.

__import__ is not recommended now.

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
An implementation of the built-in __import__() function.

Note Programmatic importing of modules should use import_module() instead of this function.

Lizabethlizard answered 7/8, 2016 at 12:4 Comment(7)
It does work thanks, but it doesn't work to import a function or variable inside one of these files starting with a number. If I do: an_imported_file = importlib.import_module('13_file'), then I can't do from an_imported_file import var_x. Is there anything that can be done to achieve this?Macromolecule
/usr/local/bin/python3.7 "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py" Traceback (most recent call last): File "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py", line 7, in <module> from an_imported_file import var_x ModuleNotFoundError: No module named 'an_imported_file'Macromolecule
Also, the line ` from an_imported_file import var_x ` in Pycharm is underlined in red...Macromolecule
I don't know sorry. My general advice is to avoid doing this.Lizabethlizard
@Macromolecule Just use an_imported_file.var_xAntonelli
@Macromolecule I have the same question even though I have my own answer to it. I would try this. an_imported_file = importlib.import_module('13_file'); var_x = an_imported_file.var_xCustomable
@Macromolecule yes, it should be no surprise that code that imports a file dynamically, by checking the value of a string when it runs, is not something that the IDE can sanity-check for correctness ahead of time.Selfassurance
T
5

The file directory structure is as follows:

 daily
   -- 20210504
         permutations.py
         __init__.py
   __init__.py

You can import the permutations module by __import__ or importlib.import_module.

The official documentation recommends using importlib.import_module.

import(name, globals=None, locals=None, fromlist=(), level=0) -> module

Import a module. Because this function is meant for use by the Python interpreter and not for general use, it is better to useimportlib.import_module()to programmatically import a module.

What is the difference?

If implemented using __import__. For example:

res = __import__('daily.20210504.permutations')

The result of res is the daily module. daily module

So, if you want to get the permutations module, you need to provide the fromlist parameter, which is written as follows.

res = __import__('daily.20210504.permutations', fromlist=('daily.20210504'))

The result of res can be seen now as enter image description here That's the right result.

What if I use importlib.import_module?

res = importlib.import_module('daily.20210504.permutations')

this allows you to get the permutations module directly.

Truitt answered 4/5, 2021 at 4:10 Comment(0)
M
-1

Don't use the .py extension in your imports.

Does from 8puzzle import * work?

For what it's worth, from x import * is not a preferred Python pattern, as it bleeds that module's namespace into your current context.

In general, try to import things you specifically want from that module. Any global from the other module can be imported.

e.g., if you have 8puzzle.foo you could do `from 8puzzle import

Edit:

While my .py message is correct, it isn't sufficient.

The other poster's __import__('8puzzle') suggestion is correct. However, I highly recommend avoiding this pattern.

For one, it's reserved an internal, private Python method. You are basically breaking the fundamental assumptions of what it means to be able to import a module. Simply renaming the file to something else, like puzzle8, will remedy this.

This will frustrate the hell out of experienced Python programmers who are expecting to know what your imports are at the top and are expecting code to (try to) conform to PEP8.

Mayence answered 1/2, 2012 at 2:55 Comment(2)
sorry about the confusing. What I did was from 8puzzle import * and I edited my original question. And it doesn't work as mvanveen said.Synod
That is my bad. I forgot that module filenames can't start witha number. I've posted an edit.Mayence

© 2022 - 2024 — McMap. All rights reserved.