module
module即是模块,在python中指一个.py文件
package
package(包),在python中为了避免多个.py文件名重复,而把他们分开,所用的一种目录结构
例如:在一个helloapp包下面写了test.py文件,那么在别的地方依然可以写一个命名为test的.py文件,有一点需要注意的是,包必须要有__init__.py文件,init.py文件指的就是helloapp目录名,和普通目录不同的是,一个包作为一个命名空间。
helloapp
├─ init.py
├─ abc.py
└─ test.py
普通目录当然也可以导入文件,但是缺失__init__.py文件使得在导入包的时候会发生有趣的事情:这并没有产生错误,解释器创建了一个由所有包含匹配包名的目录组成的列表。特殊的包命名空间模块被创建,只读的目录列表副本被存储在其__path__变量中。 举个例子:
如果将myC和myD都加到python模块路径并尝试导入会发生什么
>>> import sys
>>> sys.path.extend(['myC','myD'])
>>> import spam.blah
>>> import spam.grok
>>>
直接可以导入了,此时spam被看做一个命名空间(亲测无效,本人在测试时,并不能这样导入,之所以这么写是因为python3-cookbook书上是这么写的。链接https://python3-cookbook.readthedocs.io/zh_CN/latest/c10/p05_separate_directories_import_by_namespace.html)
>>> import spam
>>> spam.__path__
_NamespacePath(['myD\\spam','myC\\spam'])
>>>
可以用__file__属性测试,一个包是否被作为一个包命名空间的主要方法是检查其__file__属性。如果没有,那包是个命名空间。
>>> spam.__file__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'
>>> spam
<module 'spam' (namespace)>
>>>
命名空间
多个命名空间中可以有相同的名字,一个命名空间中,目录名或文件名不能相同。