下面演示 module 的使用,包含变量的引用、函数的引用和引用类型的引用。
模块定义
- module_demo.py
- # 变量
- num = 37
- #函数
- def calc(a, b):
- return a + b
- #类
- class person:
- def speak(self):
- print "i am a person."
- p = person()
模块使用
- module_usage.py
- import module_demo
- print module_demo.num
- print module_demo.calc(1, 2)
- module_demo.p.speak()
运行结果
- 37
- 3
- i am a person
到这里,我们已经了解了模块的引入和使用,那么在现实中我们很可能需要引入多个模块,应该如何做呢?答案是用逗号分隔就可以了。如下所示:
模块使用
- module_usage.py
- import module_demo, module_demo2
- ...
这里值得补充的是,引入是可以使用别名的,使用 as 关键字就可以了。
模块使用
- module_usage.py
- import module_demo, module_demo2 as demo
- ...
如果我们仅仅希望引用模块中的某个(些)对象呢,我们可以单独引入么?答案是可以的,使用如下:
模块使用
- module_usage2.py
- from module_demo import calc, p
- print calc(1, 2)
- p.speak()
从上面的案例中我们发现,我们引入多个对象时,只需要逗号分割就好了。
这里稍微需要注意的是 * 的使用,比如我们使用
,我们会以为这是导入模块中所有的对象,通常情况下确实如此,但是如果该模块中定义了如下内容:
- from module_demo import *
- __all__ = [ 'bar', 'spam' ] # 定义使用 `*` 可以导入的对象
你就得小心注意了,这时候 * 仅仅代表 all 所定义的对象,其他的对象不会被导入。
敲黑板 关键问题来了,这个 import 可以出现在代码的任何位置,那如果我们多次引入会发生什么呢?
- 模块中的代码*仅仅*在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。
多个关系密切的模块应该组织成一个包,以便于维护和使用。这项技术能有效避免名字空间冲突。创建一个名字为包名字的文件夹并在该文件夹下创建一个 init.py 文件就定义了一个包。你可以根据需要在该文件夹下存放资源文件、已编译扩展及子包。
举例来说,一个包可能有以下结构:
- Graphics/
- __init__.py
- Primitive/
- __init__.py
- lines.py
- fill.py
- text.py
- ...
- Graph2d/
- __init__.py
- plot2d.py
- ...
- Graph3d/
- __init__.py
- plot3d.py
- ...
- Formats/
- __init__.py
- gif.py
- png.py
- tiff.py
- jpeg.py
import 语句使用以下几种方式导入包中的模块:
- import Graphics.Primitive.fill#导入模块Graphics.Primitive.fill,
- 只能以全名访问模块属性,
- 例如Graphics.Primitive.fill.floodfill(img, x, y, color).from Graphics.Primitive import fill#导入模块fill,
- 只能以fill.属性名这种方式访问模块属性,
- 例如fill.floodfill(img, x, y, color).from Graphics.Primitive.fill import floodfill#导入模块fill,
- 并将函数floodfill放入当前名称空间,
- 直接访问被导入的属性,例如floodfill(img, x, y, color).
无论一个包的哪个部分被导入, 在文件 init.py 中的代码都会运行. 这个文件的内容允许为空, 不过通常情况下它用来存放包的初始化代码。导入过程遇到的所有 init.py 文件都被运行. 因此 import Graphics.Primitive.fill 语句会顺序运行 Graphics 和 Primitive 文件夹下的 init.py 文件.
下边这个语句具有歧义:
- from Graphics.Primitive import *
这个语句的原意图是想将 Graphics.Primitive 包下的所有模块导入到当前的名称空间. 然而, 由于不同平台间文件名规则不同 (比如大小写敏感问题), Python 不能正确判定哪些模块要被导入. 这个语句只会顺序运行 Graphics 和 Primitive 文件夹下的 init.py 文件. 要解决这个问题,应该在 Primitive 文件夹下面的 init.py 中定义一个名字 all 的列表,例如:
- # Graphics/Primitive/__init__.py
- __all__ = ["lines","text","fill",...]
这样, 上边的语句就可以导入列表中所有模块.
下面这个语句只会执行 Graphics 目录下的 init.py 文件,而不会导入任何模块:
- import Graphics
- Graphics.Primitive.fill.floodfill(img,x,y,color) # 失败!
不过既然 import Graphics 语句会运行 Graphics 目录下的 init..py 文件, 我们就可以采取下面的手段来解决这个问题:
- #Graphics / __init__.py import Primitive,
- Graph2d,
- Graph3d#Graphics / Primitive / __init__.py import lines,
- fill,
- text,
- ...
这样 import Graphics 语句就可以导入所有的子模块 (只能用全名来访问这些模块的属性).
来源: http://www.bubuko.com/infodetail-1994761.html