import、module和package
Package vs Module
模块是最小的代码组织单元,包是一组模块的集合。
Module是Code的集合(亦是namespace),Package是Module的集合(亦是namespace)。
Module和Package都可以被import。但Module被import时,代码可见,Package被import时,只有__init__.py的代码可见。
Module可以被直接执行,Package被间接执行,实际执行的是__main__.py的代码。
package
├── __init__.py
├── main.py
├── subpackage1
│ └── module1.py
└── subpackage2
└── module2.py
目录层级结构是客观存在的,层级关系用. 号表示。
在运行时,package和module必须先import后才能被引用。
但Module被import时,代码可见,Package被import时,只有__init__.py的代码可见。
如下所示,虽然pacakge 被引入了,但是其下的subpackage1 无法被直接索引到。
>>> import package
>>> package.subpackage1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'package' has no attribute 'subpackage1'
但是其中的类和函数可以通过. 索引到。
>>> # 类A在__init__.py中被定义
>>> package.A
<class 'package.A'>
这是因为,首次引入package后,只执行了__init__.py的代码内容,所以pacakge的namespace中只有类A,是没有subpackage1 和subpackage2的。
>>> dir(package)
['A', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
通过import子包/模块,package的namespace会相应增加。
>>> import package.subpackage1.module1
>>> dir(package)
['A', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'subpackage1']
Modules vs Scripts
同一个code文件,在不同侧重的用法时,有时被称作module,有时称作script。
通常modules被用于imported,scripts被用于直接执行。
希望直接执行module时,需要使用解释器的-m 选项。
-m 选项在sys.path 中搜索module名称,然后以__main__ 作为module的名称执行代码。
sys.path
执行python脚本时,脚本所在路径会加到sys.path中。
python $dir/script.py ...
所以在非包调用时,脚本script.py 如果需要其他$dir下的其他module,可以直接import。
# script.py
import submodule
...
#