A package is a group of related modules, directories and code, they extend modules and designed to handle very large Python projects.
Its probaly easier to show an example first and then explain the various elements of packages
Package example | ################## ## packageStart.py ################## from package import * # determined by the __all__ in __init__.py file print("This is the packageStart file, version: " + version) module1.mod1() # module2.mod2() # excluded from __all__ in __init__.py file, compile error if you include it ################## ## __init__.py ################## print("This is the __init__.py script") version = "1.0" # __all__ = ['module1', 'module2', 'version'] __all__ = ['module1', 'version'] # allow the visibility of modules, variables ################## ## module1.py ################## def mod1(): print("Module 1 method mod1") # if __name__ == '__main__': # add this if you don't want below to run, when executing start script print("This is module 1") ################## ## module2.py ################## def mod2(): print("Module 2 method mod2") # if __name__ == '__main__': # add this if you don't want below to run, when executing start script print("This is module 2") |
using the example above the main program is the packageStart.py file, when you execute this file and import anything from package it runs the __init__.py file, this servers two purposes
The __init__.py can be empty, but I have provided a few examples on what you can do with this file, the first line is simply a print statement to prove that it is executed when you import the package from another file, the version variable can used to version control files, etc. Lastly we see the __all__ attribute and it works with the import package from * command, this attribute limits what is imported, anything declared in the __all__ attribute is allowed to be imported (using the from ... import *), anything else won't be. In my example I left out module2 and thus module2 is not imported and hence why I hashed out the code in packageStart.py, the compiler complains.
You can create as complex structure as you need and use the __init__.py file to limit modules usage and pass variables down to modules. However a better way to hide names is make them private.