Mr. B
Mr. B

Reputation: 2706

Why does this Python3 module appear to perform a relative import of itself?

If I create a module named 'json.py' with the following contents:

#! python
import json as _json
JSONDecoder = _json.JSONDecoder

..shouldn't the 'import json as _json' statement perform an absolute import, and therefore provide the python standard-lib JSON module?

..instead, if I execute or import this module, I get:

$ python --version
Python 3.4.0
$ python relative_import/json.py 
Traceback (most recent call last):
  File "relative_import/json.py", line 3, in 
    import json as _json
  File "/home/silver/Projects/relative_import/json.py", line 6, in 
    JSONDecoder = _json.JSONDecoder
AttributeError: 'module' object has no attribute 'JSONDecoder'
$

..which shows that 'json' is importing itself (a relative import). ..I imagine I'm missing something -- python's import system has always made natural and intuitive sense to me, but in this case I'm lost.

Edit: I'm using python 3.4

Edit: For anyone interested, this is what occurred: I have a package which includes a module called 'json', which replaces the system 'json'. This is fine (IMO), however, I also started a script that was in the same package folder (temporarily) but not meant to ultimately be a part of the same module. Thus, the following occurred:

Solution: Move the script to my package's 'bin' folder, or, if I want it to be a part of the package proper, use python -m packagename.foo

Thank you, @Martijn Pieters.

Upvotes: 0

Views: 180

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122232

It is doing an absolute import.

The directory the main script lives in is added to sys.path, and as a result the first json found is your script. You are running python relative_import/json.py and Python thus adds relative_import/ to sys.path.

Note that the main script is named __main__, so import json does import the script file as a separate, new module object. Your code is in effect loaded twice.

See the Interface options documentation:

If the script name refers directly to a Python file, the directory containing that file is added to the start of sys.path, and the file is executed as the __main__ module.

Upvotes: 3

Related Questions