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
...
#