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.
CodePudding user response:
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
.