Python Playbook - Ch10 Modules and Packages === ###### tags: `python` `presentation` ## 10.1. Making a Hierarchical Package of Modules > Organize your code on the file system and make sure that every directory defines an ```__init__.py``` file. ```shell graphics/ __init__.py primitive/ __init__.py line.py fill.py text.py formats/ __init__.py png.py jpg.py ``` ```python= import graphics.primitive.line from graphics.primitive import line import graphics.formats.jpg as jpg ``` ## 10.2. Controlling the Import of Everything Define a variable ```__all__``` in your module that explicitly lists the exported names. ```python from somemodule import * # somemodule.py def spam(): pass def grok(): pass blah = 42 # Only export 'spam' and 'grok' __all__ = ['spam', 'grok'] ``` ## 10.3. Importing Package Submodules Using Relative Names 1. Import a module located in the same directory: ```python # in line.py (see 10.1) from . import fill ``` 2. Import a module located in a different directory: ```python # in line.py (see 10.1) from ..formats import png ``` ## 10.4. Splitting a Module into Multiple Files A program module can be split into separate files by turning it into a package. ```python from mymodule.a import A from mymodule.b import B # or from mymodule import A, B ``` ## 10.5. Making Separate Directories of Code Import Under a Common Namespace To unify separate directories under a common namespace 1. omit \_\_init\_\_.py files in the directories where the components are going to join together. ```shell foo-package/ spam/ blah.py bar-package/ spam/ grok.py ``` 2. Add into Python Module path ```python import sys sys.path.extend(['foo-package', 'bar-package']) import spam.blah import spam.grok ``` 3. use ```__path__``` to check namespaces ```python >>>import spam >>> spam.__path__ >>>_NamespacePath(['foo-package/spam', 'bar-package/spam']) ``` 4. Namespace module should not have attribute ```__file__``` ## 10.6. Reloading Modules To reload a previously loaded module, use [module].reload(). :::warning :warning: reload() does not update definitions that have been imported using statements such as ```from module import name```. ::: ## 10.7. Making a Directory or Zip File Runnable As a Main Script If ``__main__.py`` is present, you can simply run the Python interpreter on the top-level directory like this: ```bash % python3 myapplication ``` The interpreter will execute the ```__main__.py``` file as the main program. ## 10.8. Reading Datafiles Within a Package The ```pkgutil.get_data()``` function is meant to be a high-level tool for getting a datafile regardless of where or how a package has been installed. ```python import pkgutil data = pkgutil.get_data(__package__, 'somedata.dat') ``` > The built-in I/O functions such as open() have to be programmed to use **absolute** filenames. ## 10.9. Adding Directories to sys.path :question: You have Python code that can’t be imported because it’s not located in a directory listed in sys.path. You can 1. Add them through the use of the **PYTHONPATH** environment variable ```bash % env PYTHONPATH=/some/dir:/other/dir python3 ``` 2. Create a .pth file that lists the directories, and place it into one of Python’s ++site-packages++ directories. ```bash # myapplication.pth /some/dir /other/dir ``` > Reference: [撥開 Python, pip, site-packages 的藍色蜘蛛網](https://medium.com/@will.wang/%E6%92%A5%E9%96%8B-python-pip-site-packages-%E7%9A%84%E8%97%8D%E8%89%B2%E8%9C%98%E8%9B%9B%E7%B6%B2-90e398bb3785) > Reference: [Python 的 Import 陷阱](https://medium.com/pyladies-taiwan/python-%E7%9A%84-import-%E9%99%B7%E9%98%B1-3538e74f57e3) ## 10.10. Importing Modules Using a Name Given in a String Use the ```importlib.import_module()``` function to manually import a module or part of a package where the name is given as a string. ## 10.11. Loading Modules from a Remote Machine Using Import Hooks This particular solution involves installing an instance of a special finder object UrlMetaFinder as the last entry in sys.meta_path. Whenever modules are imported, thefinders in ```sys.meta_path``` are consulted in order to locate the module. [```importlib.abc```](https://docs.python.org/3/library/importlib.html) – Abstract base classes related to import ![](https://i.imgur.com/bavAFvA.png) ## 10.12. Patching Modules on Import Use the same import hook machinery as 10.11. ![](https://i.imgur.com/1fpDO94.png) ```python sys.meta_path.insert(0, PostImportFinder()) ``` ## 10.13. Installing Packages Just for Yourself To force packages to install in this directory, give the --user option to the installation command. For example: ```shell python3 setup.py install --user ``` or ```shell pip install --user packagename ``` ## 10.14. Creating a New Python Environment You can make a new “virtual” environment using the ```pyvenv``` command. ```bash= % pyvenv Spam % ls bin include lib pyvenv.cfg ``` ## 10.15. Distributing Packages If you’re going to start giving code away, make sure the 1. ```setup.py``` 2. ```MANIFEST.in``` files appear in the top-level directory of yourpackage. **[Reference]** [Python application 的打包和发布——(上)](http://wsfdl.com/python/2015/09/06/Python%E5%BA%94%E7%94%A8%E7%9A%84%E6%89%93%E5%8C%85%E5%92%8C%E5%8F%91%E5%B8%83%E4%B8%8A.html)