Inside the folder "models" your Python modules will see only the files and folders inside, and whatever is on PYTHONPATH.
Then, you use either the full name of the "Domain" folder, including the project name:
from meuprojeto.domain.person import Person
Or use relative import by adding a "." in addition to the first in the prefix
module, for each folder you want to "go up":
from ..domain.person import Person
(It only works if that particular.py file is imported as part of the whole project as well, that is, its path will be meuprojeto.models.person_model
)
In both cases, it is necessary that Python is viewing its module hierarchy as a package - that is, it is necessary that the "meuprojeto", above the folders "Domain" and "models" is in Pythonpath. In general, when we create a Python project, this most external folder will have a "setup.py" file with the installation information - if you have setup.py, run the "Pip install -e." in this folder (above the "myproject") - this will consider that the project you are editing and creating is part of the Python environment you are using. Then, being in any folder on your computer, you can only call the specific file with a line like python3 -m meuprojeto.models.person_model
. If you don’t have setup.py, just call the interpreter from that folder, above the "meuprojeto", or include it in the environment variable "PYTHONPATH".
"exporting"
In Python, all objects of all modules are visible to any code - what defines whether they are public or not is the convention: if the name of the file, variable or object starts with "_", users of this project/module should not mess with it directly. So there is no need to export -
Now in practice, it is common to have "more public" things than others - let’s assume that within your "Domain/person.py" file there are several helper-functions that make sense for the methods of the Person class, but that there is no reason for someone "from the outside" to use. Harvesting all these functions as "private" with names starting with "_" will only disrupt their readability.
What you usually do is expose the highest-level class - the names the user of your project will actually use - in the file __init__.py
of each folder.
So you could inside the domain.__init__.py
one from .person import Person
. Then other packages that will use this model will do:
from meuprojeto.domain import Person
(instead of from meuprojeto.domain.person import Person
).
In large projects, it may be desirable not to keep editing the __init__
to include all classes of all files in that folder, so it might be ok to have some code using for
and introspection of the file system even to make imports automatically - but this type of code generally stays in the framework, not in the project.
And, for the purpose of making the answer complete, Python also makes use of the module variable __all__
to indicate which names will be imported with "*" in that module.
So, going back to the case that "Persons.py" has some classes that you want to leave as "more public", and several helper-functions and module variables - you can at the end of the file persons.py
place:
__all__ = ["Person", "OtherPerson", "VIPerson"] # (as classes públicas)
and in the __init__.py
corresponding use from .person import *
, to bring only the objects that have the names in __all__
Would not be
from domain.product import Product
what do you want?– Woss
The intention is exactly not to need access to
domain.product
so I can get to this class. In Typescript this is called "Barrel", I’m seeing how I could use this feature in Python to be clearer the logic of the solutions– LeandroLuk
But in TS you didn’t
import { Person } from '../domain'
? Access the same "Domain", no?– Woss
For you to access
Person
, that’s insidedomain
, it has to be declared as exported inside the index file, otherwise you have to access her file directly usingdomain/person
...– LeandroLuk