Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python import precedence: packages or modules?

I wasn't clear how to correctly name this question.

Case 1

Assume that I have the following directory structure.

foo
|
+- bar/__init__.py
|
+- bar.py

If I have

from foo import bar

How do I know which bar (bar.py or bar/__init__.py) is being imported? Is there any easy way to automatically detect this from occurring?

Case 2

foo
|
+- foo.py
|
+- other.py

If other.py has the line

import foo

How do I know which foo (foo or foo.foo) is being imported? Again, is tehre any easy way to automatically detect this from occurring?

like image 611
Jeeyoung Kim Avatar asked Nov 03 '10 22:11

Jeeyoung Kim


People also ask

Does the order of imports matter in Python?

Import order does not matter. If a module relies on other modules, it needs to import them itself. Python treats each . py file as a self-contained unit as far as what's visible in that file.

Are Python modules the same as packages?

A Python package is nothing but a collection of modules along with a __init__.py file. The modules can also be arranged in hierarchy of folders inside a package. Just by adding an empty __init__.py file to the in the folder, Python knows it is a Package.

Should imports be at the top of file Python?

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

Are packages and modules the same?

A module is a file containing Python code in run time for a user-specific code. A package also modifies the user interpreted code in such a way that it gets easily functioned in the run time.


2 Answers

TLDR; a package takes precedence over a module of the same name if they are in the same directory.

From the docs:

"When a module named spam is imported, the interpreter searches for a file named spam.py in the current directory, and then in the list of directories specified by the environment variable PYTHONPATH. This has the same syntax as the shell variable PATH, that is, a list of directory names."

This is a bit misleading because the interpreter will also look for a package called spam (a directory called spam containing an __init__.py file). Since the directory entries are sorted before searching, packages take precedence over modules with the same name if they are in the same directory because spam comes before spam.py.

Note that "current directory" is relative to the main script path (the one where __name__ == '__main__' is True). So if you are at /home/billg calling /foo/bar.py, "current directory" refers to /foo.

like image 89
Paulo Scardine Avatar answered Sep 20 '22 16:09

Paulo Scardine


from a python shell:

from foo import bar

print bar.__file__

should tell you which file has been imported

Rob

like image 32
rtmie Avatar answered Sep 18 '22 16:09

rtmie