第三屆 Python Deep Dive I : Package

Deep Dive into Python Packages

What are Packages? - Lecture

  • Packages are specilaized modules

    • they can contains modules
    • packages can contains packages (sub-packages)
    • If a module is a package, it must have a value set for __path__
    • Both modules and packages do not have to be entities in the file system, but typically they are.
  • Packages represent a hierarchy of modules / packages (Modules → packages - > packages)

  • Import nested packages

  • Let’s focus on (File based) packages

    • A package is simply a module tha can contain other modules/packages
    • On file system we therefore have to use directories for packages, and modules are the files
    • Directory name => Package name => the Code of the Package (__init__.py inside the directory)
    • Module file name => module_name.py
    • To define a package in our file system, we must
      • Create a directory whose name will be the package name
      • Create a file call __init__.py inside that directory => tells Pythons that the directory is a package
  • While a file based package get imported

  • Nested package

  • Three Dunder Properties (__file__, __package__) (__path__ - Package only property)

    • For Modules
      • __file__ => the location of module code in the file system (include the module file name)
      • __package__ => the package that the module code is located in
      • __path__ => an empty string if the module is located in the application root => ‘’
    • For Packages
      • __file__ => the location of __init__.py in the file system (include the file name)
      • __package__ => package name
      • __path__ => the location of package(directory) in the file system => Fully Qualiified Path
  • The package hierarchy - an example and the dunder properties

  • sub-package and the dunder properties

  • More examples



What are Packages? - Coding

  • import pack1.pack1_1

    • sys.modules
      • ‘pack1.pack1_1’ in sys.modules => \color{tomato}{True}
      • ‘pack1_1’ in sys.modules => False
      • ‘pack1’ in sys.modules => False
    • globals()
      • ‘pack1’ in globals() => \color{tomato}{True}
      • ‘pack1_1’ in globals() => False
      • ‘pack1.pack1_1’ in globals() => False
    • pack1.pack1_1.value => ‘pack1_1 value’
    • pack1.value => ‘pack1 value’
  • from pack1 import pack1_1 => Put the symbol directly into global namespace

    • ‘pack1_1’ in globals() => \color{tomato}{True}
    • id(pack1_1) == id(sys.modules[‘pack1.pack1_1’]) => \color{tomato}{True}
  • import pack1.pack1_1.module1_1a

    • sys.modules
      • ‘pack1’ in sys.modules() => True
      • ‘pack1.pack1_1’ in sys.modules() => True
      • ‘pack1.pack1_1.module1_1a’ in sys.modules() => True
    • globals()
      • ‘pack1’ in globals() => \color{tomato}{True}
      • ‘pack1.pack1_1’ in globals() => False
      • ‘pack1.pack1_1.module1_1a’ in globals() => False
      • pack1.pack1_1.module1_1a.value => ‘module1_1a value’

Why Packages?

The benefits for the developers

  1. 模組化

    • 重用性:模組化讓你將功能拆分成多個小的、獨立的部件,每個部件專注於特定的功能。這樣可以在不同的項目中重複使用相同的程式碼,而不需要重新編寫。
    • 可維護性:將程式碼分解為較小的模組可以使每個模組更易於理解和修改。當你需要修改某個功能時,可以專注於相關的模組,而不是整個程式庫。
  2. 版本控制

    • 版本管理:每個 package 可以有自己的版本號碼,這樣開發者可以追蹤功能變更和修復,並控制不同版本之間的兼容性。
    • 兼容性:package 管理工具(如 pip)會確保安裝的 package 與其他 package 兼容。這有助於避免因為 package 版本不兼容而導致的問題。
  3. 測試

    • 單元測試:開發者可以為 package 的各個模組編寫單元測試,這樣可以及早發現和修復錯誤,保證每個模組的功能正確。
    • 持續集成:持續集成工具可以自動化測試和部署過程,確保每次程式碼更改後 package 都能正常運行。
  4. 部署與協同合作

    • 容易部署:將 package 上傳到 PyPI 等公共平台後,其他開發者可以輕鬆地通過 pip 安裝這些 package,簡化了部署的過程。
    • 協同開發:通過版本控制系統(如 Git)來管理 package 的源代碼,可以方便地進行協作開發,合併程式碼和處理版本控制問題。
  5. 說明文件

    • 內建說明文件:可以在 package 中包括說明文件,例如使用 Sphinx 生成的 API 文檔,這有助於使用者理解如何使用 package 提供的功能。

The benefits for the users

  1. 簡化安裝

    • 相依管理:通過 pip 等工具,使用者可以輕鬆安裝 package (含其相依性),避免手動配置和安裝的麻煩。
    • 一致性:確保安裝的程式庫版本與開發者測試的版本一致,這有助於避免環境配置的不一致問題。
  2. 提高效率

    • 即開即用:許多程式庫提供了開箱即用的功能,使用者無需從頭開始編寫程式碼,只需調用 package 提供的 API 即可。
    • 功能封裝:將複雜的功能封裝在 package 中,使用者只需要調用簡單的接口,即可完成複雜的操作。
  3. 說明文件和範例

    • 學習資源:大多數 package 都會附帶詳細的文檔和使用範例,幫助使用者快速理解如何使用 package 提供的功能。
    • 示範程式:提供示範程式幫助用戶理解 package 的使用方法,通常在檔案中包含示範程式碼,可以加快上手速度。

Structuring Packages - Part 1 & 2

  • Nest packages => How we can roll things up into a nicer namespace infrastructure for the users of our package

  • root

  • 2nd common(package)

  • 3rd validators(package)

  • 4th numeric(module)

  • The whole idea is that we want to

    • Hide the implementation details (users don’t need to know how our code is structured)
    • Independent of the name of the package name (e.g. make it easier to rename common to shared)
    • Flatten the structure out and make the entire model a little simpler to understand
  • The technique we use to accomplish this

    • Using relative import

    • Controlling what gets imported when someone does an import *

      • 1st method( \color{tomato}{selected}) - use __all__ = [‘function1’, ‘function2’]


      • 2nd method - If Python sees an underscore infront of a function, it is not going to put it into the namespace.

  • About __init__.py, it should be used for importing other modules and subpackages, not for defining functions, classes, etc.

  • the built-in asyncio package

  • the buit-in email package (with some functions in the __init__.py file)

Namespace Packages

  • What are Implicit namespace packages


  • Regular vs. Namespace Packages

  • an example

  • Conclusion (About namespace package)

    • You can spread namespace packages over different parts of your disk, even into zip files
    • You can’t manipulate and flatten the namespace the way we did with the regular packages
    • Read PEP 420 for more details

Importing from Zip Archives

  • import sys
  • sys.path.append(r’.\common.zip’)
1 Like