Skip to content
Advertisement

How to call direct imports of libraries in the creation of a Python package

Background

I’m trying to create a Python package with a semi-complicated structure. I have published a few packages before, and because they were simple, I put all the classes and functions necessary in __init__.py itself. For example, the file structure of one of my simple packages would be:

Package/
    venv # my virtual environment
    package-name/
        __init__.py
    setup.py # with setuptools, etc.

A sample __init__.py file from a sample package would be:

# __init__.py from a sample simple package
import requests

class User:
    def __init__(self, something):
        self.something = requests.get(url).json()['something']

    def do_something(self):
        return float(self.something) * 10

As a sample package like this is basic and only requires the User class, this would suffice. On installing the package with pip, using import package-name works to call the User object.

# random computer with simple package installed
import package_name

api = package_name.User()

And this works fine.

Question

A more complicated package like the one I’m working on cannot contain all classes and functions directly in the __init__.py file. The structure is below:

Package/
    venv # my virtual environment
    package-name/
        __init__.py
        related.py
        something.py
    setup.py

The problem is that I can’t quite figure out how to get the contents of related.py and something.py to work implicitly. By implicitly, I mean that when the user executes import package_name, they can use package_name.attribute to access any attributes from any of the files, whether it’s in __init__.py, related.py, or something.py.

Currently, if I structure the __init__.py file like this:

# complex package __init__.py
from package_name import related
from package_name import something

The user still has to call related and something as attributes of package_name:

# random computer user file with package_name installed
import package_name

x = package_name.related.x()
y = package_name.something.y()

I want them to be able to do this instead:

# random computer user file with package_name installed
import package_name

x = package_name.x()
y = package_name.y()

Without having to themselves write: from package_name import related and from package_name import something on their own computer.

Apologies for the long question but I wanted to be as clear as possible about what I’m asking because there are a lot of moving parts.

Advertisement

Answer

Whatever names are available in your __init__.py will be available as package_name.whatever when someone does import package_name. So if you want to make names from submodules available, you can do from package_name.related import x (or from .related import x) inside your __init__.py.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement