一 .module

通常模块为一个文件,直接使用import来导入就好了。可以作为module的文件类型有".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"。

二. package

通常包总是一个目录,可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 __init__.py。然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。
 
 一.模块你可以使用import语句将一个源代码文件作为模块导入.例如:

  1. # file : spam.py
  2. a = 37                    # 一个变量
  3. def foo:                  # 一个函数
  4. print "I'm foo"
  5. class bar:                # 一个类
  6. def grok(self):
  7. print "I'm bar.grok"
  8. b = bar()                 # 创建一个实例

使用import spam 语句就可以将这个文件作为模块导入。系统在导入模块时,要做以下三件事:

1.为源代码文件中定义的对象创建一个名字空间,通过这个名字空间可以访问到模块中定义的函数及变量。
2.在新创建的名字空间里执行源代码文件.
3.创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量,如:

  1. import spam           # 导入并运行模块 spam
  2. print spam.a          # 访问模块 spam 的属性
  3. spam.foo()
  4. c = spam.bar()

用逗号分割模块名称就可以同时导入多个模块:

  1. import socket, os, regex

模块导入时可以使用 as 关键字来改变模块的引用对象名字:

  1. import os as system
  2. import socket as net, thread as threads
  3. system.chdir("..")
  4. net.gethostname()

使用from语句可以将模块中的对象直接导入到当前的名字空间. from语句不创建一个到模块名字空间的引用对象,而是把被导入模块的一个或多个对象直接放入当前的名字空间:

  1. from socket import gethostname # 将gethostname放如当前名字空间
  2. print gethostname()            # 直接调用
  3. socket.gethostname()           # 引发异常NameError: socket

from语句支持逗号分割的对象,也可以使用星号(*)代表模块中除下划线开头的所有对象:

  1. from socket import gethostname, socket
  2. from socket import *   # 载入所有对象到当前名字空间

不过,如果一个模块如果定义有列表__all__,则from module import * 语句只能导入__all__列表中存在的对象。

  1. # module: foo.py
  2. __all__ = [ 'bar', 'spam' ]     # 定义使用 `*` 可以导入的对象

另外, as 也可以和 from 联合使用:

  1. from socket import gethostname as hostname
  2. h = hostname()

import 语句可以在程序的任何位置使用,你可以在程序中多次导入同一个模块,但模块中的代码*仅仅*在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。sys.modules字典中保存着所有被导入模块的模块名到模块对象的映射。这个字典用来决定是否需要使用import语句来导入一个模块的最新拷贝.

from module import * 语句只能用于一个模块的最顶层.*特别注意*:由于存在作用域冲突,不允许在函数中使用from 语句。 
每个模块都拥有 __name__ 属性,它是一个内容为模块名字的字符串。最顶层的模块名称是 __main__ .命令行或是交互模式下程序都运行在__main__ 模块内部. 利用__name__属性,我们可以让同一个程序在不同的场合(单独执行或被导入)具有不同的行为,象下面这样做:

  1. # 检查是单独执行还是被导入
  2. if __name__ == '__main__':
  3. # Yes
  4. statements
  5. else:
  6. # No (可能被作为模块导入)
  7. statements

模块搜索路径
导入模块时,解释器会搜索sys.path列表,这个列表中保存着一系列目录。一个典型的sys.path 列表的值:
Linux:
['', '/usr/local/lib/python2.0',
     '/usr/local/lib/python2.0/plat-sunos5',
     '/usr/local/lib/python2.0/lib-tk',
     '/usr/local/lib/python2.0/lib-dynload',
     '/usr/local/lib/python2.0/site-packages']
Windows:
['', 'C:\\WINDOWS\\system32\\python24.zip', 'C:\\Documents and Settings\\weizhong', 'C:\\Python24\\DLLs', 'C:\\Python24\\lib', 'C:\\Python24\\lib\\plat-win', 'C:\\Python24\\lib\\lib-tk', 'C:\\Python24\\Lib\\site-packages\\pythonwin', 'C:\\Python24', 'C:\\Python24\\lib\\site-packages', 'C:\\Python24\\lib\\site-packages\\win32', 'C:\\Python24\\lib\\site-packages\\win32\\lib', 'C:\\Python24\\lib\\site-packages\\wx-2.6-msw-unicode']
空字符串 代表当前目录. 要加入新的搜索路径,只需要将这个路径加入到这个列表. 
 
模块导入和汇编
到现在为止,本章介绍的模块都是包含Python源代码的文本文件. 不过模块不限于此,可以被 import 语句导入的模块共有以下四类: 
•使用Python写的程序( .py文件)
•C或C++扩展(已编译为共享库或DLL文件)
•包(包含多个模块)
•内建模块(使用C编写并已链接到Python解释器内)
当查询模块 foo 时,解释器按照 sys.path 列表中目录顺序来查找以下文件(目录也是文件的一种): 
1.定义为一个包的目录 foo
2.foo.so, foomodule.so, foomodule.sl,或 foomodule.dll (已编译扩展)
3.foo.pyo (只在使用 -O 或 -OO 选项时)
4.foo.pyc
5.foo.py
 
对于.py文件,当一个模块第一次被导入时,它就被汇编为字节代码,并将字节码写入一个同名的 .pyc文件.后来的导入操作会直接读取.pyc文件而不是.py文件.(除非.py文件的修改日期更新,这种情况会重新生成.pyc文件) 在解释器使用 -O 选项时,扩展名为.pyo的同名文件被使用. pyo文件的内容虽去掉行号,断言,及其他调试信息的字节码,体积更小,运行速度更快.如果使用-OO选项代替-O,则文档字符串也会在创建.pyo文件时也被忽略.
如果在sys.path提供的所有路径均查找失败,解释器会继续在内建模块中寻找,如果再次失败,则引发 ImportError 异常. 
.pyc和.pyo文件的汇编,当且仅当import 语句执行时进行. 
当 import 语句搜索文件时,文件名是大小写敏感的。即使在文件系统大小写不敏感的系统上也是如此(Windows等). 这样, import foo 只会导入文件foo.py而不会是FOO.PY.
 
重新导入模块
如果更新了一个已经用import语句导入的模块,内建函数reload()可以重新导入并运行更新后的模块代码.它需要一个模块对象做为参数.例如: 
import foo
... some code ...
reload(foo)          # 重新导入 foo
在reload()运行之后的针对模块的操作都会使用新导入代码,不过reload()并不会更新使用旧模块创建的对象,因此有可能出现新旧版本对象共存的情况。 *注意* 使用C或C++编译的模块不能通过 reload() 函数来重新导入。记住一个原则,除非是在调试和开发过程中,否则不要使用reload()函数.
 
2.包
多个关系密切的模块应该组织成一个包,以便于维护和使用。这项技术能有效避免名字空间冲突。创建一个名字为包名字的文件夹并在该文件夹下创建一个__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语句使用以下几种方式导入包中的模块:

  1. import Graphics.Primitive.fill #导入模块Graphics.Primitive.fill,只能以全名访问模块属性,例如 Graphics.Primitive.fill.floodfill(img,x,y,color).
  2. from Graphics.Primitive import fill# 导入模块fill ,只能以 fill.属性名这种方式访问模块属性,例如 fill.floodfill(img,x,y,color).
  3. 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文件.

下边这个语句具有歧义:

  1. from Graphics.Primitive import *

这个语句的原意图是想将Graphics.Primitive包下的所有模块导入到当前的名称空间.然而,由于不同平台间文件名规则不同(比如大小写敏感问题), Python不能正确判定哪些模块要被导入.这个语句只会顺序运行 Graphics 和 Primitive 文件夹下的__init__.py文件. 要解决这个问题,应该在Primitive文件夹下面的__init__.py中定义一个名字all的列表,例如:

  1. # Graphics/Primitive/__init__.py
  2. __all__ = ["lines","text","fill",...]

这样,上边的语句就可以导入列表中所有模块.

下面这个语句只会执行Graphics目录下的__init__.py文件,而不会导入任何模块:

  1. import Graphics
  2. Graphics.Primitive.fill.floodfill(img,x,y,color)  # 失败!

不过既然 import Graphics 语句会运行 Graphics 目录下的 __init__..py文件,我们就可以采取下面的手段来解决这个问题:

  1. # Graphics/__init__.py
  2. import Primitive, Graph2d, Graph3d
  3. # Graphics/Primitive/__init__.py
  4. import lines, fill, text, ...

这样import Graphics语句就可以导入所有的子模块(只能用全名来访问这些模块的属性).

sys.path 和sys.modules
sys.path包含了module的查找路径;
sys.modules包含了当前所load的所有的modules的dict(其中包含了builtin的modules);

[python]模块及包的更多相关文章

  1. Python/模块与包之模块

    Python/模块与包之模块 1.什么是模块? 模块就是py文件 2.为什么要用模块? 如果在解释器上进行编码,把解释器关闭之前写的文件就不存在了,如果使用模块的话就能永久保存在磁盘中. 3.如何使用 ...

  2. Python模块、包、异常、文件(案例)

    Python模块.包.异常.文件(案例) python.py #模块 # Python中的模块(Module),是一个Python文件,以.py文件结尾,包含了Python对象定义和Python语句, ...

  3. 【Python】解析Python模块与包

    模块 模块是非常简单的Python文件,单个Python文件就是一个模块,两个文件就是两个模块. import语句是用来导入模块或者从模块里导入特定的类或者函数.如前面我们用过的math模块,从而可以 ...

  4. python 模块和包深度学习理解

    python 模块和包 简单说相当于命名空间 1,python 模块        python模块就是一个文件,里面有函数,变量等 import 模块 模块.方法 from 模块 import fu ...

  5. (三)运用Python模块和包

    1 引言 为了能够在Python项目中高效地运用Python模块和包,我们需要进一步地来了解它们是如何在Python项目中进行定义.使用和工作的. 2 Python模块和包 Python模块和包的基本 ...

  6. Python模块04/包/logging日志

    Python模块04/包/logging日志 目录 Python模块04/包/logging日志 内容大纲 1.包 2.logging日志 3.今日总结 内容大纲 1.包 2.logging日志 1. ...

  7. Python模块和包

    模块和包是python组织代码的基本方式. 模块: python的每一个脚本文件都可称之为模块,模块的名称就是脚本的文件名.例如当我们写了一个test.py的脚本文件,则可以在同目录下的另外一个脚本m ...

  8. python模块与包的导入

    1. 模块与包的区别 模块,即module,一个包含python语句的.py文件就是一个模块!每个源代码文件都会自动成为模块!没有额外的语法用来声明模块. 包,又称模块包,即module packag ...

  9. python模块及包的导入

    一.模块 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py".".pyo".".pyc".&q ...

  10. 简述Python模块和包

    我们常常会使用别人写的包,假如我们使用的是Python3.4版本,安装在windows的C盘根目录下,那么外部的包一般放在:C:\Python34\Lib\sit-packages下,此目录下有以.p ...

随机推荐

  1. EM64T和64位是不是一个概念啊?他们有什么区别啊,怎么区分啊?

    首先我们要解决什么是64位这个问题.究竟什么是64位处理器呢?64 bit是相对于32 Bit而言的,这个位数指的是CPU GPRs(General-Purpose Registers,通用寄存器)数 ...

  2. Vue.js:路由

    ylbtech-Vue.js:路由 1.返回顶部 1. Vue.js 路由 本章节我们将为大家介绍 Vue.js 路由. Vue.js 路由允许我们通过不同的 URL 访问不同的内容. 通过 Vue. ...

  3. Vue.js:template

    ylbtech-Vue.js: 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   7.返回顶部   8.返回顶部   9.返回顶部   1 ...

  4. thinkphp中的session的使用和理解!

    session的作用:session可以长时间的保存数据,不丢失. session的常用于: 1.登录,保存登录信息 2.保存购物车信息 3.保存验证码信息 定义session常量 define('W ...

  5. 张瀚荣:如何用UE4制作3D动作游戏

    转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...

  6. python开发模块基础:序列化模块json,pickle,shelve

    一,为什么要序列化 # 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化'''比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?现在我们能想到的方法就是存在文 ...

  7. SQL语句替换字段内容例子

    SELECT REPLACE(SysFuncID,'7201','7204') ,           CASE           WHEN Flag=1 THEN REPLACE(funcname ...

  8. 不同浏览器对于html5 audio标签和音频格式的兼容性

    音频格式 Chrome Firefox IE9 Opera Safari OGG 支持 支持 支持 支持 不支持 MP3 支持 不支持 支持 不支持 支持 WAV 不支持 支持 不支持 支持 不支持 ...

  9. Swift中用正规表达式判断String是否是手机号码

    func isTelNumber(num:NSString)->Bool { var mobile = "^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$&qu ...

  10. CBV中的dispatch

    之前介绍了FBV和CBV ,下面我们看一下CBV中的dispatch dispatch函数在类View中定义,作用就是通过反射查找get或post函数,所以在执行get或post函数之前,dispat ...