Importing classes / functions with the same name as the module

Let's say I am using a python package with the following structure:

package/
   bar.py
   foo.py
   __init__.py

      

bar.py

contains a class bar

and foo.py

contains a function foo

. When I want to import a function / class I need to write

from package.bar import bar
from package.foo import foo

      

or i can write

from package import bar
from package import foo

      

More generally: Can I always omit the class / function name when importing a module with the same name as the class / function?

+3


source to share


1 answer


No, you cannot omit the name of a module or object. There is no mechanism that implicitly makes such an import.

From Zen of Python :

Explicit is better than implicit.

Note that the import of the module itself must always be valid. If from package import bar

imported the object package.bar.bar

instead, then you'll have to get out of the way to access the module itself package.bar

.

Moreover, this implicit behavior (automatic import of the object contained in the module, not the module itself) leads to confusing inconsistencies.

  • What adds import package.bar

    to your namespace? Will the link package.bar

    be a module or a contained object?
  • What should happen to code that imports such a name when renaming the contained object? Can I from package import bar

    provide you with a module? Some operations will still succeed, leading to strange, hard-to-debug errors instead of an explicit exception ImportError

    .


Generally speaking, Python modules rarely contain just one thing. Python is not Java, modules are made up of closely related groups of objects, not just one class or function.

Packages now have an internal name clash; from package import foo

can refer to both the names set in the module package

and the name of the nested module. In this case, Python will look at the namespace first package

.

This means that you can make a clear decision to provide facilities foo

and bar

at the package level, to package/__init__.py

:

# in package/__init__.py
from .foo import foo
from .bar import bar

      

Now from package import foo

and from package import bar

will provide you with these objects masking nested modules.

The general mechanism for importing objects from submodules into the package namespace is a common method of composing your public API while also using internal modules to logically group your code. For example, an json.JSONDecodeError

exception
in the Python standard library is defined in a module json.exceptions

and then imported into json/__init__.py

. However, I generally discouraged masking submodules; but foo

also bar

into a module with a different name.

+3


source







All Articles