Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference to the top-level module in Python inside a package?

Tags:

In the below hierachy, is there a convenient and universal way to reference to the top_package using a generic term in all .py file below? I would like to have a consistent way to import other modules, so that even when the "top_package" changes name nothing breaks.

I am not in favour of using the relative import like "..level_one_a" as relative path will be different to each python file below. I am looking for a way that:

  1. Each python file can have the same import statement for the same module in the package.
  2. A decoupling reference to "top_package" in any .py file inside the package, so whatever name "top_package" changes to, nothing breaks.

    top_package/   __init__.py   level_one_a/     __init__.py     my_lib.py     level_two/       __init__.py       hello_world.py   level_one_b/     __init__.py     my_lib.py   main.py 
like image 461
hllau Avatar asked Jan 02 '12 23:01

hllau


People also ask

How do you define a top level package in Python?

Hence, if you want to get the top package name, you just need to get the first component of the path and import it using __import__ . Despite the variable name used to access the package is still called top_package , you can rename the package and if will still work.

How do you reference a module in Python?

You need to use the import keyword along with the desired module name. When interpreter comes across an import statement, it imports the module to your current program. You can use the functions inside a module by using a dot(.) operator along with the module name.


2 Answers

This should do the job:

top_package = __import__(__name__.split('.')[0]) 

The trick here is that for every module the __name__ variable contains the full path to the module separated by dots such as, for example, top_package.level_one_a.my_lib. Hence, if you want to get the top package name, you just need to get the first component of the path and import it using __import__.

Despite the variable name used to access the package is still called top_package, you can rename the package and if will still work.

like image 90
jcollado Avatar answered Sep 28 '22 02:09

jcollado


Put your package and the main script into an outer container directory, like this:

container/     main.py     top_package/         __init__.py         level_one_a/             __init__.py             my_lib.py             level_two/                 __init__.py                 hello_world.py         level_one_b/             __init__.py             my_lib.py 

When main.py is run, its parent directory (container) will be automatically added to the start of sys.path. And since top_package is now in the same directory, it can be imported from anywhere within the package tree.

So hello_world.py could import level_one_b/my_lib.py like this:

from top_package.level_one_b import my_lib 

No matter what the name of the container directory is, or where it is located, the imports will always work with this arrangement.

But note that, in your original example, top_package it could easily function as the container directory itself. All you would have to do is remove top_package/__init__.py, and you would be left with efectively the same arrangement.

The previous import statement would then change to:

from level_one_b import my_lib 

and you would be free to rename top_package however you wished.

like image 27
ekhumoro Avatar answered Sep 28 '22 03:09

ekhumoro