How to access a standard-library module in Python when there is a local module with the same name?
You are looking for Absolute/Relative imports from PEP 328, available with 2.5 and upward.
In Python 2.5, you can switch import‘s behaviour to absolute imports using a from __future__ import absolute_import directive. This absolute- import behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default, import math will always find the standard library’s version. It’s suggested that users should begin using absolute imports as much as possible, so it’s preferable to begin writing from pkg import string in your code.
Relative imports are still possible by adding a leading period to the module name when using the from ... import form:
from __future__ import absolute_import
# Import uncertainties.math
from . import math as local_math
import math as sys_math
Can I import a local module with the same name as a standard-library one?
Rename your internal file to something like my_queue.py
and import it into your file like this. That avoids bad practices like from queue import *
and name conflicts with the standard library which is most likely the problem you are running into now.
import my_queue
def driver():
q = my_queue.Queue()
for line in df:
if 'received' in line:
q.enqueue(line)
print("Adding job " + new_item.job_ID + " to the queue with the timestamp: " + new_item.time_stamp + ".")
print("The prority of the job is: " + new_item.job_priority)
print("The job type is: " + new_item.job_type)
How can I import from the standard library, when my project has a module with the same name? (How can I control where Python looks for modules?)
In Python 3.5 and up, use the standard library importlib
module to import directly from a specified path, bypassing import
's lookup mechanism:
import importlib.util
import sys
# For illustrative purposes.
import tokenize
file_path = tokenize.__file__ # returns "/path/to/tokenize.py"
module_name = tokenize.__name__ # returns "tokenize"
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
In actual code, file_path
can be set to any path to a .py
file to import; module_name
should be the name of the module that will be imported (the name that the import system uses to look up the module when further import
statements are attempted). Subsequent code will use module
as the name of the module; change the variable name module
to use a different name.
To load a package instead of a single file, file_path
should be the path to the package's root __init__.py
.
How to import standard library module instead of local directory?
The problem is that the current working directory (as either ''
or '.'
, depending on version/platform) is always at the top of sys.path
when you start up Python.
Using absolute imports makes no difference—that just means to look in sys.path
first, instead of looking for relative imports before falling back to sys.path
.
The right solution is obviously to either (a) rename calendar
, or (b) move it into subpackage of some other package instead of having it at the top level. Whatever your Good Reasons are, the Good Reasons for doing the right thing are likely even better.
But if you must get around this, there are a few things you can do. The simplest is to temporarily munge sys.path
:
syspath = sys.path
sys.path = [path for path in sys.path if path.strip('.')]
import calendar
sys.path = syspath
However, no matter what you do, this is going to cause huge problems. When you later try to import your local package calendar
—even if you're doing so from a completely different source file—nothing will happen, because there's already something named calendar
in sys.modules
, so that other source file will just get the stdlib calendar
module instead of your package.
So you'll also need to rename one or the other on the fly and remove it from sys.modules
. Maybe this:
syspath = sys.path
sys.path = [path for path in sys.path if path.strip('.')]
calmod = sys.modules.get('calendar')
del sys.modules['calendar']
calendar = __import__('calendar')
sys.modules['calendar'] = calmod
sys.path = syspath
And, depending on the order at which your modules get run (which may not be easily predictable, or even deterministic), there's a good chance you'll need similar hackery in the other location.
(What if you never actually need to import your local package calendar
? Well, in that case you don't have this problem… but then I can't imagine what your Good Reasons could possibly be…)
Python 3: Import of core module when local module exists with same name?
You are correct : the better solution would be to rename that module. Hacking around the import system may lead to sad headaches down the road, and more hackeries. Break the pattern : rename the module, make everyone happy.
A poor man's solution would be to change the sys.path
order. If you manage to put the path ......./lib/site-packages
before the path to the directory containing your package containing the typing
module, and if you do that before any other module of the WHOLE Python program imports any typing
, it can work.
Here is my setup :
stack_overflow/
├─ annoying/
│ ├─ __init__.py
│ ├─ innocent.py
│ ├─ typing.py
│ ├─ main.py
# file: innocent.py
import typing
print("'typing' imported")
abc: typing.List[str] = ["a", "b", "c"]
# file: main.py
import sys
print(sys.path)
import innocent
and both __init__.py
and typing.py
are empty.
When I execute my main I get :
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
'typing' imported
Traceback (most recent call last):
[...]
AttributeError: module 'typing' has no attribute 'List'
because the wrong file was imported, due to the sys.path
order such that Python searched for typing
in the annoying
directory before to search in its site-packages
.
I am now putting the path to the library at the end :
# file: main.py
import sys
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
which prints :
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
[... Python regular stuff ..., 'C:\\PycharmProjects\\stack_overflow\\annoying']
'typing' imported
now that the order is reversed, Python imports typing
from its site-packages
in priority, and everything works as expected. But if I have an import (even transitive) to to module which imports a typing
before I change the sys.path
, it will fail again :
# file: main.py
import sys
import innocent # raise AttributeError: module 'typing' has no attribute 'List'
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
But messing with sys.path
is prone to errors, conflicts, pain and sadness. That's why is discouraged to reuse standard library names for user modules. So please fix the file, it really is the best solution.
Python modules with identical names (i.e., reusing standard module names in packages)
Reusing names of standard functions/classes/modules/packages is never a good idea. Try to avoid it as much as possible. However there are clean workarounds to your situation.
The behaviour you see, importing your SWS.time
instead of the stdlib time
, is due to the semantics of import
in ancient python versions (2.x). To fix it add:
from __future__ import absolute_import
at the very top of the file. This will change the semantics of import
to that of python3.x, which are much more sensible. In that case the statement:
import time
Will only refer to a top-level module. So the interpreter will not consider your SWS.time
module when executing that import inside the package, but it will only use the standard library one.
If a module inside your package needs to import SWS.time
you have the choice of:
Using an explicit relative import:
from . import time
Using an absolute import:
import SWS.time as time
So, your foo.py
would be something like:
from __future__ import absolute_import
import time
from . import time as SWS_time
python module names with same name as existing modules
In Python 2, imports in packages without a package qualifier indeed first look for package local modules.
Thus, import pyglet
will find msa.pyglet
before the top-level pyglet
is considered.
Switch to absolute imports to make the Python 3 behaviour the default, where unqualified names are always top level names:
from __future__ import absolute_import
Now import pyglet
can only ever find the top-level name, never msa.pyglet
. To reference other modules within your msa
namespace, use from . import pyglet
or from msa import pyglet
.
See PEP 328 -- Imports: Multi-Line and Absolute/Relative for more details.
Importing a python standard library with the same name as the current module
First, it is bad practice to create a module that shadows another module. However, that doesn't prevent you from proceeding.
Import __future__ import absolute_import
as your first import in your main
file.
This forces imports to use absolute paths instead of relative. Now, import email
imports that standard library. You can import your local version by from . import email
Python 3: importing different python modules with same name
I think you should be using the PYTHONPATH
variable in order to avoid using sys
.
Content of a/a.py
and b/b.py
:
import utils
utils.hello()
Content of X/utils.py
with X
one of a
, b
or c
:
def hello():
print('hello from X')
Content of c/main.py
:
import a.a
import b.b
import utils
utils.hello()
Output (when running: export PYTHONPATH='$PYTHONPATH:<project_root>'; python main.py
):
hello from a
hello from b
hello from c
Related Topics
Screenshot of Inactive Window Printwindow + Win32Gui
Get Loop Count Inside a For-Loop
Python Daemon and Systemd Service
How to Set "Camera Position" for 3D Plots Using Python/Matplotlib
How to Add Hours to Current Time in Python
Preprocessing in Scikit Learn - Single Sample - Depreciation Warning
Why Is the Empty Dictionary a Dangerous Default Value in Python
Converting Between Datetime and Pandas Timestamp Objects
Python Requests.Get Always Get 404
Paging/Scrolling Through Set of 2D Heat Maps in Matplotlib
Use Aws Glue Python with Numpy and Pandas Python Packages
Multiprocessing VS Multithreading VS Asyncio in Python 3
What Is the Most Efficient Way of Counting Occurrences in Pandas
Sorting a 2D Numpy Array by Multiple Axes
Fix Not Load Dynamic Library for Tensorflow Gpu
Finding Elements Not in a List
Use of True, False, and None as Return Values in Python Functions
Matching Any Character Including Newlines in a Python Regex Subexpression, Not Globally