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
.