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.