模块和包

封装包很简单。在文件系统上组织代码,并确保每个目录都定义了init.py文件

(http://upload-images.jianshu.io/upload_images/5404975-b7ee232e7acbb9e7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如果这样做了就可以如下导入文件:

import graphics.primitive.line
from graphics.primitive import line
import graphics.formats.jpg as jpg

文件init.py的目的是
要包含不同运行级别的包的可选的初始化代码。 举个例子,如果你执行了语句import graphics, 文件graphics/init.py将被导入,建立graphics命名空间的内容。像import graphics.format.jpg这样导入,文件graphics/init.py和文件graphics/graphics/formats/init.py将在文件graphics/formats/jpg.py导入之前导入。

绝大部分时候让init.py空着就好。但是有些情况下可能包含代码。 举个例子,
init.py能够用来自动加载子模块:

# graphics/formats/__init__.py
from . import jpg
from . import png

像这样一个文件,用户可以仅仅通过import grahpics.formats来代替import graphics.formats.jpg以及import graphics.formats.png。

敏锐的程序员会发现,即使没有init.py文件存在,python仍然会导入包。如果你没有定义init.py时,实际上创建了一个所谓的“命名空间包”,万物平等,如果你着手创建一个新的包的话,包含一个init.py文件吧。

2.如何控制模块被全部导入的内容

当使用’from module import *‘语句时,希望对从模块或包导出的符号进行精确控制。可以在你的模块中定义一个变量 all 来明确地列出需要导出的内容。

# somemodule.py
def spam():
pass
def grok():
pass
blah = 42
# Only export 'spam' and 'grok'
__all__ = ['spam', 'grok']

尽管强烈反对使用 ‘from module import *‘,但是在定义了大量变量名的模块中频繁使用。
如果你不做任何事,这样的导入将会导入所有不以下划线开头的。 另一方面,如果定义了all ,那么只有被列举出的东西会被导出。如果你将 all 定义成一个空列表,没有东西将被导出。 如果 all 包含未定义的名字,在导入时引起AttributeError。

3.使用相对路径名导入包中子模块

(http://upload-images.jianshu.io/upload_images/5404975-7e0574544f79a14e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

# mypackage/A/spam.py
from . import grok

# mypackage/A/spam.py
from ..B import bar

4.如何合并多个文件合并成一个单一的逻辑命名空间
程序模块可以通过变成包来分割成多个独立的文件。考虑下下面简单的模块

模块和包_第1张图片
image.png

假设你想mymodule.py分为两个文件,每个定义的一个类。要做到这一点,首先mymodule目录来替换文件mymodule.py。 这这个目录下,创建以下文件:

(http://upload-images.jianshu.io/upload_images/5404975-75a4450c7e399a2c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

模块和包_第2张图片
模块和包_第3张图片

你可能感兴趣的:(模块和包)