Python基础(12)--模块

模块简介

如果你退出 Python 解释器重新进入,以前创建的一切定义(变量和函数)就全部丢失了。因此,如果你想写一些长久保存的程序,最好使用一个文本编辑器来编写程序,把保存好的文件输入解释器。我们称之为创建一个脚本。程序变得更长一些了,你可能为了方便维护而把它分离成几个文件。你也可能想要在几个程序中都使用一个常用的函数,但是不想把它的定义复制到每一个程序里。  

为了满足这些需要,Python提供了一个方法可以从文件中获取定义,在脚本或者解释器的一个交互式实例中使用。这样的文件被称为模块;模块中的定义可以导入到另一个模块或主模块中(在脚本执行时可以调用的变量集位于最高级,并且处于计算器模式)  

模块是包括Python 定义和声明的文件。文件名就是模块名加上 .py 后缀。模块的模块名(做为一个字符串)可以由全局变量 __name__ 得到。例如,你可以用自己惯用的文件编辑器在当前目录下创建一个叫 fibo.py 的文件,录入如下内容: 

# Fibonacci numbers module
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b
def fib2(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

现在进入Python解释器,用如下命令导入这个模块:

>>> import fibo

这样做不会直接把 fibo中的函数导入当前的语义表;它只是引入了模块名 fibo。你可以通过模块名按如下方式访问这个函数: 

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> print '\n',fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

如果你想要直接调用函数,通常可以给它赋一个本地名称:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

深入模块

模块可以像函数定义一样包含执行语句。这些语句通常用于初始化模块。它们只在模块第一次导入时执行一次。

对应于定义模块中所有函数的全局语义表,每一个模块有自己的私有语义表。因此,模块作者可以在模块中使用一些全局变量,不会因为与用户的全局变量冲突而引发错误。

另一方面,如果你确定你需要这个,可以像引用模块中的函数一样获取模块中的全局变量,形如:modname.itemname

模块可以导入(import)其它模块。习惯上所有的 import语句都放在模块(或脚本,等等)的开头,但这并不是必须的。被导入的模块名入在本模块的全局语义表中。

import 语句的一个变体直接从被导入的模块中导入命名到本模块的语义表中。例如: 

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

这样不会从局域语义表中导入模块名(如上所示, fibo没有定义)。这样可以导入所有除了以下划线(_)开头的命名。 

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

这样可以导入所有除了以下划线(_)开头的命名。 

模块搜索路径

导入一个叫 spam 的模块时,解释器先在当前目录中搜索名为 spam.py 的文件,然后在环境变量PYTHONPATH 表示的目录列表中搜索,然后是环境变量PATH 中的路径列表。如果 PYTHONPATH 没有设置,或者文件没有找到,接下来搜索安装目录。

实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录),PYTHONPATH

和安装目录。这样就允许Python程序(原文如此,programs;我猜想应该是“programer”,程序员--译者)了解如何修改或替换模块搜
索目录。需要注意的是由于这些目录中包含有搜索路径中运行的脚本,所以这些脚本不应该和标准模块重名,否则在导入模块时Python会尝试把这些脚本当作
模块来加载。这通常会引发一个错误。

“编译”Python文件 

对于引用了大量标准模块的短程序,有一个提高启动速度的重要方法,如果在 spam.py 所在的目录下存在一个名为 spam.pyc 的文件,它会被视为 spam 模块的预“编译”版本。用于创建 spam.pyc 的这一版 spam.py 的修改时间记录在 spam.pyc 文件中,如果两者不匹配,.pyc 文件就被忽略。

通常你不需要为创建 spam.pyc 文件做任何工作。一旦 spam.py 成功编译,就会试图编译对应版本的 spam.pyc。如果有任何原因导致写入不成功,返回的 spam.pyc 文件就会视为无效,随后即被忽略。 spam.pyc 文件的内容是平台独立的,所以Python模块目录可以在不同架构的机器之间共享。 

部分高级技巧:

  • 以 -O 参数调用Python解释器时,会生成优化代码并保存在 .pyo 文件中。现在的优化器没有太多帮助;它只是删除了断言(assert )语句。使用 -O 参参数,所有的代码都会被优化;.pyc 文件被忽略, .py文件被编译为优化代码。
  • 向Python解释器传递两个 -O 参数(-OO)会执行完全优化的二进制优化编译,这偶尔会生成错误的程序。现在的优化器,只是从二进制代码中删除了 __doc__ 符串,生成更为紧凑的 .pyo 文件。因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。
  • 来自 .pyc 文件或 .pyo 文件中的程序不会比来自 .py 文件的运行更快; .pyc 或 .pyo 文件只是在它们加载的时候更快一些。
  • 通过脚本名在命令行运行脚本时,不会将为该脚本创建的二进制代码写入 .pyc 或.pyo 文件。当然,把脚本的主要代码移进一个模块里,然后用一个小的解构脚本导入这个模块,就可以提高脚本的启动速度。也可以直接在命令行中指定一个 .pyc 或 .pyo 文件。
  • 对于同一个模块(这里指例程 spam.py),可以只有 spam.pyc 文件(或者 spam.pyc ,在使用 -O 参数时)而没有 spam.py 文件。这样可以打包发布比较难于逆向工程的Python代码库。
  • 模块可以为指定目录中的所有模块创建 .pyc 文件(或者使用 .pyo 参数创建.pyo文件)。  

标准模块

Python带有一个标准模块库,并发布有独立的文档,名为 Python 库参考手册 (此后称其为“库参考手册”)。有一些模块内置于解释器之中,这些操作的访问接口不是语言内核的一部分,但是已经内置于解释器了。这既是为了提高效率,也是为了给系统调用等操作系统原生访问提供接口。这类模块集合是一个依赖于底层平台的配置选项。例如,amoeba 模块只提供对 Amoeba 原生系统的支持。有一个具体的模块值得注意:sys ,这个模块内置于所有的Python解释器。变量 sys.ps1sys.ps2定义了主提示符和副助提示符字符串:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>

这两个变量只在解释器的交互模式下有意义。

变量 sys.path 是解释器模块搜索路径的字符串列表。它由环境变量 PYTHONPATH 初始化,如果没有设定 PYTHONPATH ,就由内置的默认值初始化。你可以用标准的字符串操作修改它:

>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')

使用sys模块

例1:使用sys模块

import sys
print 'the command line arguments are:'
for i in sys.argv:
    print i
print '\n\nThe PYTHONPATH is',sys.path, '\n'

运行结果如下:

the command line arguments are:
F:/PycharmProjects/Pytest/test.py

The PYTHONPATH is
['F:\\PycharmProjects\\Pytest',
'C:\\Python27\\lib\\site-packages\\distribute-0.6.27-py2.7.egg',
'C:\\Python27\\Lib\\site-packages\\wx-3.0-msw', 'D:\\chardet-2.3.0',
'F:\\PycharmProjects\\Pytest', 'C:\\Windows\\system32\\python27.zip',
'C:\\Python27\\DLLs', 'C:\\Python27\\lib',
'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk',
'C:\\Python27', 'C:\\Python27\\lib\\site-packages',
'C:\\Python27\\lib\\site-packages\\setuptools-0.6c11-py2.7.egg-info']

dir()函数

The built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings:

内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表: 

import fibo,sys
print dir(fibo)
print '\n',dir(sys)

运行结果如下:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'fib', 'fib2']

['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__name__', '__package__', '__plen', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace', 'getwindowsversion', 'hexversion', 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'py3kwarning', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions', 'winver']

无参数调用时, dir() 函数返回当前定义的命名: 

a=[1,2,3,4,5]
import fibo,sys
fibo=fibo.fib
print dir()

运行结果如下:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'fibo', 'sys']

该列表列出了所有类型的名称:变量,模块,函数,等等:

dir() 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 __builtin__中定义: 

>>> import __builtin__
>>> dir(__builtin__)

运行结果如下:

['ArithmeticError',
'AssertionError', 'AttributeError', 'BaseException', 'BufferError',
'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis',
'EnvironmentError', 'Exception', 'False', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'IndentationError', 'IndexError', 'KeyError',
'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None',
'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',
'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError',
'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning',
'WindowsError', 'ZeroDivisionError', '__debug__', '__doc__',
'__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply',
'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex',
'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate',
'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format',
'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print',
'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr',
'reversed', 'round', 'set', 'setattr', 'slice', 'sorted',
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr',
'unicode', 'vars', 'xrange', 'zip']

包 Packages

包通常是使用用“圆点模块名”的结构化模块命名空间。例如,名为 A.B 的模块表示了名为 "B" 的包中名为 "A" 的子模块。正如同用模块来保存不同的模块架构可以避免全局变量之间的相互冲突,使用圆点模块名保存像 NumPy 或 Python Imaging Library 之类的不同类库架构可以避免模块之间的命名冲突。

假设你现在想要设计一个模块集(一个“包”)来统一处理声音文件和声音数据。存在几种不同的声音格式(通常由它们的扩展名来标识,例如:.wav , .aiff , .au)

),于是,为了在不同类型的文件格式之间转换,你需要维护一个不断增长的包集合。可能你还想要对声音数据做很多不同的操作(例如混音,添加回声,应用平衡
功能,创建一个人造效果),所以你要加入一个无限流模块来执行这些操作。你的包可能会是这个样子(通过分级的文件体系来进行分组):  

Sound/                          Top-level package
      __init__.py               Initialize the sound package
      Formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      Effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      Filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

导入模块时,Python通过 sys.path 中的目录列表来搜索存放包的子目录。

必须要有一个 __init__.py 文件的存在,才能使Python视该目录为一个包;这是为了防止某些目录使用了"string" 这样的通用名而无意中在随后的模块搜索路径中覆盖了正确的模块。最简单的情况下,__init__.py 可以只是一个空文件,不过它也可能包含了包的初始化代码,或者设置了 __all__ 变量,后面会有相关介绍。包用户可以从包中导入合法的模块,例如:

import Sound.Effects.echo

这样就导入了 Sound.Effects.echo 子模块。它必需通过完整的名称来引用。 

Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

导入包时有一个可以选择的方式:

from Sound.Effects import echo

这样就加载了 echo 子模块,并且使得它在没有包前缀的情况下也可以使用,所以它可以如下方式调用:

echo.echofilter(input, output, delay=0.7, atten=4)

还有另一种变体用于直接导入函数或变量:

from Sound.Effects.echo import echofilter

这样就又一次加载了 echo 子模块,但这样就可以直接调用它的 echofilter() 函数:

echofilter(input, output, delay=0.7, atten=4)

需要注意的是使用 from package import item 方式导入包时,这个子项(item)既可以是包中的一个子模块(或一个子包),也可以是包中定义的其它命名,像函数、类或变量。import 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 ImportError 异常。

相反,使用类似import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。 

时间: 2024-09-01 05:57:09

Python基础(12)--模块的相关文章

Python的SQLalchemy模块连接与操作MySQL的基础示例_python

一.SQLalchemy简介SQLAlchemy是一个开源的SQL工具包,基本Python编程语言的MIT许可证而发布的对象关系映射器.SQLAlchemy提供了"一个熟知的企业级全套持久性模式,使用ORM等独立SQLAlchemy的一个优势在于其允许开发人员首先考虑数据模型,并能决定稍后可视化数据的方式.二.SQLAlchempy的安装首先需安装mysql,这里就不再多说了..... 然后,下载SQLAlchemy(http://www.sqlalchemy.org/download.html

举例详解Python中smtplib模块处理电子邮件的使用_基础知识

在基于互联网的应用中,程序经常需要自动地发送电子邮件.如:一个网站的注册系统会在用户注册时发送一封邮件来确认注册:当用户忘记登陆密码的时候,通过邮件来取回密码.smtplib模块是python中smtp(简单邮件传输协议)的客户端实现.我们可以使用smtplib模块,轻松的发送电子邮件.下面的例子用了不到十行代码来发送电子邮件:   #coding=gbk import smtplib smtp = smtplib.SMTP() smtp.connect("smtp.yeah.net"

举例详解Python中smtplib模块处理电子邮件的使用

  这篇文章主要介绍了举例详解Python中smtplib模块处理电子邮件的使用,是Python入门学习中的基础知识,需要的朋友可以参考下 在基于互联网的应用中,程序经常需要自动地发送电子邮件.如:一个网站的注册系统会在用户注册时发送一封邮件来确认注册;当用户忘记登陆密码的时候,通过邮件来取回密码.smtplib模块是python中smtp(简单邮件传输协议)的客户端实现.我们可以使用smtplib模块,轻松的发送电子邮件.下面的例子用了不到十行代码来发送电子邮件: ? 1 2 3 4 5 6

Python基础入门之seed()方法的使用

 这篇文章主要介绍了Python基础入门之seed()方法的使用,是Python学习当中的基础知识,需要的朋友可以参考下     seed() 设置生成随机数用的整数起始值.调用任何其他random模块函数之前调用这个函数. 语法 以下是seed()方法的语法: ? 1 seed ( [x] ) 注意:此函数是无法直接访问的,所以需要导入seed模块,然后需要使用random静态对象来调用这个函数. 参数 x -- 这是下一个随机数的种子.如果省略,则需要系统时间,以产生下一个随机数. 返回值

Python之路【2】:Python基础

入门拾遗 一.作用域 只要变量在内存中就能被调用!但是(函数的栈有点区别) 对于变量的作用域,执行声明并在内存中存在,如果变量在内存中存在就可以被调用. 1 if 1==1: 2 name = 'tianshuai' 3 print name 所以下面的说法是不对的: 外层变量,可以被内层变量使用 内层变量,无法被外层变量使用 二.三元运算 1 result = 值1 if 条件 else 值2 例子: 1 name = raw_input("please input your name: &q

python基础学习笔记(一)

安装与运行交互式解释器       在绝大多数linux和 UNIX系统安装中(包括Mac OS X),Python的解释器就已经存在了.我们可以在提示符下输入python命令进行验证(作者环境ubuntu) fnngj@fnngj-H24X:~$ python Python 2.7.3 (default, Sep 26 2012, 21:53:58) [GCC 4.7.2] on linux2 Type "help", "copyright", "cre

python异步并发模块concurrent.futures简析

本文主要介绍python异步并发模块concurrent.futures.它非常简单易用,主要用来实现多线程和多进程的异步并发. 1. 模块安装 1) python 3.x中自带了concurrent.futures模块 2) python 2.7需要安装futures模块,使用命令pip install futures安装即可 pypi地址:https://pypi.python.org/pypi/futures/ 2. Executor对象 class concurrent.futures.

Python基础教程之字符串

1 基本字符串操作 2 字符串格式化:精简版 2.1 用字符串格式化操作符 2.2 用string的Template格式化字符串 3 字符串格式化:完整版 3.1 转换说明符 3.2 简单转换 3.3 字段宽度和精度 3.4 符号,对齐和 0 填充 4 字符串方法 4.1 find 4.2 join 4.3 lower 4.4 replace 4.5 split 4.6 strip 4.7 translate 1 基本字符串操作 说明:字符串也是序列的一种,所以分片,乘法,索引,求长度,最大,

python 基础知识

python 基础知识 本文所有内容是学习期间做的笔记,仅为个人查阅和复习方便而记录.所有内容均摘自:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 数据类型 整数 浮点数 字符串 如果字符串内部既包含'又包含",可以用转义字符\来转义. 多行字符串可以通过'''字符串内容'''来表示 r''表示''内部的字符串默认不转义 布尔值, true, false:布尔值可以用and.o