Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python import mechanics

I have two related Python 'import' questions. They are easily testable, but I want answers that are language-defined and not implementation-specific, and I'm also interested in style/convention, so I'm asking here instead.

1)

If module A imports module B, and module B imports module C, can code in module A reference module C without an explicit import? If so, am I correct in assuming this is bad practice?

2)

If I import module A.B.C, does that import modules A and A.B as well? If so, is it by convention better to explicitly import A; import A.B; import A.B.C?

like image 536
Cory Petosky Avatar asked Dec 16 '09 21:12

Cory Petosky


People also ask

How do Python imports work?

In Python, you use the import keyword to make code in one module available in another. Imports in Python are important for structuring your code effectively. Using imports properly will make you more productive, allowing you to reuse code while keeping your projects maintainable.

How do I import a Python file?

If you have your own python files you want to import, you can use the import statement as follows: >>> import my_file # assuming you have the file, my_file.py in the current directory. # For files in other directories, provide path to that file, absolute or relative.

What are the three methods to import modules in Python?

So there's four different ways to import: Import the whole module using its original name: pycon import random. Import specific things from the module: pycon from random import choice, randint. Import the whole module and rename it, usually using a shorter variable name: pycon import pandas as pd.

What are the types of import in Python?

There are generally three groups: standard library imports (Python's built-in modules) related third party imports (modules that are installed and do not belong to the current application) local application imports (modules that belong to the current application)


2 Answers

The first thing you should know is that the Python language is NOT an ISO standard. This is rather different from C/C++, and it means that there's no "proper" way to define a language behaviour - CPython might do something just because it was coded that way, and Jython might do the other way round.

about your questions, remember that "importing" a module is a two-part operation: first the module is loaded - if it had never been, e.g. if it wasn't available in sys.modules, then a name is bound to that module in the local namespace.

hence:

1) Yes, you can reference whatever you want from module a by providing the proper namespace, e.g. you'll have to do something like

B.C.name = "something"

And I think this is very rarely done in Python programs and could be considered bad practice since it forces a "transitive dep" - if some module B implementation is refactored and doesn't depend on C anymore, it should continue offering the C module just for satisfying A deps.

Of course setting __ all __ can prevent this, and a good practice may be to put __ all __ in all your modules, and export just the symbols you want to be really public.

2) Yes and no. Doing

import a.b.c.d 

performs the first import phase (loading) on all modules, but the second just on a (and, recursively, in b with respect to c, etc) but all the modules in the chain must be referenced by full namespace; after such an import, you can do

a.something
a.b.something
a.b.c.something

but you can't do

c.something
b.something

I must admit that kind of usage is pretty rare as well; I generally prefer the "from module import something" way-to-import, and generally you just ask for what you need - such nesting is neither common in libraries, nor its usage is that common.

Many times there're "outer packages", just used for organization, which hold modules with classes. It's very likely that a, b, c above are just packages, and d is a module which truly holds classes, functions and other objects. So the proper usage would be:

from a.b.c.d import name1, name2, name3

I hope this satifies your curiosity.

like image 133
Alan Franzoni Avatar answered Sep 25 '22 11:09

Alan Franzoni


Alan's given a great answer, but I wanted to add that for your question 1 it depends on what you mean by 'imports'.

If you use the from C import x syntax, then x becomes available in the namespace of B. If in A you then do import B, you will have access to x from A as B.x.

It's not so much bad practice as potentially confusing, and will make debugging etc harder as you won't necessarily know where the objects have come from.

like image 21
Daniel Roseman Avatar answered Sep 21 '22 11:09

Daniel Roseman