python modules versus package

包和模块的概念是编程语言级别的概念,在不同的语言中可能内部实现逻辑不同。包和模块的出现一方面方便了代码组织,另一方面有利于代码复用。

mudoles

A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.

模块(modules)就是一个python脚本文件。

模块名由__name__表示,默认和python文件名相同(不含.py)

通过import导入时,模块会被执行一次。

每个模块都有自己的私有符号表(private symbol table),作为模块内部所有函数的全局符号表(global symbol table

Executing modules as scripts

直接执行模块脚本python解释器会把__name__设置为__main__

python fibo.py <arguments>  

The Module Search Path

  • 当前路径
  • PYTHONPATH
  • sys.path

注意,如果导入的是包,而包内的模块相互引用,可以通过.表示。下面是python的json标准包内部模块:

./json
├── decoder.py
├── encoder.py
├── __init__.py
├── __pycache__
├── scanner.py
└── tool.py

__init__.py中引用decode和encode模块的方法是:

from .decoder import JSONDecoder, JSONDecodeError  
from .encoder import JSONEncoder  

"Compiled" Python files

为了加快导入速度,python会把包内文件预编译放在包的__pycache__目录中,预编译文件中包含python解释器的版本:

➜  json tree -L 1 __pycache__ 
__pycache__  
├── decoder.cpython-36.opt-1.pyc
├── decoder.cpython-36.opt-2.pyc
├── decoder.cpython-36.pyc
├── encoder.cpython-36.opt-1.pyc
├── encoder.cpython-36.opt-2.pyc
├── encoder.cpython-36.pyc
├── __init__.cpython-36.opt-1.pyc
├── __init__.cpython-36.opt-2.pyc
├── __init__.cpython-36.pyc
├── scanner.cpython-36.opt-1.pyc
├── scanner.cpython-36.opt-2.pyc
├── scanner.cpython-36.pyc
├── tool.cpython-36.opt-1.pyc
├── tool.cpython-36.opt-2.pyc
└── tool.cpython-36.pyc

Standard Modules

The dir() Function

dir()以list形式返回列表包含的函数、属性。

dir() does not list the names of built-in functions and variables.If you want a list of those, they are defined in the standard module builtins.

Packages

包是为了更好的组织代码/模块,有效避免了名称冲突。包必须包含__init__.py文件,init模块在import时起作用,它包含了包的元信息和元操作

包中还可以包含子包:

sound/                          Top-level package  
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

import可以中包中导入子包,也可以导入模块。

Importing * From a Package

从包中导入__all__中定义的元素,可以是类,也可以是方法等。避免将包中的信息全部导入。

Intra-package References

包内部子包/子模块间的相对导入

__path__表示包/模块的路径位置 __file__表示模块/包的文件位置,如果是包的话会显示__init__.py的位置。

>>> import adolph
>>> adolph.__path__
['/usr/lib/python3.6/site-packages/adolph']
>>> adolph.__file__
'/usr/lib/python3.6/site-packages/adolph/__init__.py'  

问题

  • 对于一个模块,在没有定义一些属性的情况下,为什么会有file,name等属性
  • 如何找到一个模块/包的父类