Reputation: 33
I have a folder with three files:
time.py and datetime.py are identical:
def ticks_ms():
return 5
When test.py looks like this:
import datetime as t
print(t.ticks_ms())
it prints 5. If I change it to:
import time as t
print(t.ticks_ms())
I get:
AttributeError: module 'time' has no attribute 'ticks_ms'
Why can I shadow the datetime module but not the time module?
Upvotes: 0
Views: 223
Reputation: 160437
Why can I shadow the
datetime
module but not thetime
module?
Because Python will first search for built-in modules (implemented in C) before searching for normal .py
files (in various locations, starting from your cwd
, see the contents of sys.path
).
You can see this by inspecting sys.meta_path
which contains finders that are queried when an import for a module occurs (a module which hasn't been found in sys.modules
):
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>,
<class '_frozen_importlib.FrozenImporter'>,
<class '_frozen_importlib_external.PathFinder'>]
First in this list is BuiltinImporter
which, as it's name implies, handles the finding of built-in modules.
The time module is built-in (see sys.builtin_module_names
for a list of these):
>>> time
<module 'time' (built-in)>
and is found before a search for your time.py
is performed. While datetime.py
isn't:
>>> datetime
<module 'datetime' from '/home/jim/anaconda3/lib/python3.6/datetime.py'>
and so the datetime.py
in your current working dir masks it (PathFinder
finds datetime.py
by looking at the entries listed in sys.path
).
Yes, you can re-order the finders in sys.meta_path
and put the PathFinder
first thereby resulting in time.py
getting found but, please don't do that (unless you're just experimenting :-).
Upvotes: 2