542505989 发表于 2015-4-22 08:54:16

python学习笔记之九:模块和包

  Python的标准安装包括一组模块,称为标准库。这里介绍模块的工作方式,学习如何使用它们。
  一. 模块
  1.1 用import从外部模块获取函数并为自己的程序所用:



>>> from math import sqrt
>>> import math
  1.2 编写自己的模块
  任何python程序都可以作为模块导入。程序保存的位置很重要。假设我们所写的程序叫hello.py被保存在c:/python目录下,可以执行以下的代码,告诉解释器在哪里寻找hello.py模块:



#hello.py
print "hello,world!"
>>> import sys
>>> sys.path.append('c:/python')
>>> import hello
hello,world!
  如上所见,在导入模块时,其中的代码被执行了。不过如果再次导入该模块,就什么都不会发生了。因为导入模块并不意味着在导入时执行某些操作,它们主要用于定义,只需要定义一次,导入模块一次和多次的效果是一样的。
  1.3 模块用于定义
  导入模块真正的用处在于保持自己的作用域,这意味着定义的所有类和函数以及赋值后的变量都成了模块的特性。
  (1)我们可以在模块底下定义函数,然后像标准库那样导入它们。
  (2)我们还可以在模块中增加测试代码来检查模块本身是否正常工作:
  有2种办法加入测试代码:
  第一种办法是“告知”模块本身是作为程序运行还是导入到其他程序:



#hello.py
def hello():
print 'hello:__name__'
#A test:
    hello()
>>> __name__
'__main__'
>>> hello.__name__
'hello:__name__'
  第二种办法是使用条件测试代码:



#hello.py
def hello():
print 'hello'
#A test:
def test():
hello()
if __name__ == '__main__':test()
  这样如果将它作为程序运行,hello()函数会被执行,而作为模块导入时,它的行为就会像普通模块一样。
  
  1.4 让模块可用
  (1)把模块放在正确的位置:只需找出python解释器从哪里开始查找模块,然后将你自己的文件放置在那里即可。



>>> import sys
>>> print sys.path
['D:\\python', 'C:\\Python27\\Lib\\idlelib', 'C:\\Python27\\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']
  以上目录都可以用来存放我们定义的文件,但是site-packages目录是最佳选择,因为它就是用来做这些事情的。
  (2)告诉编译器哪里去找:编辑sys.path或者是在PYTHONPATH环境变量中包含模块所在目录
  
  二. 包package
  为了组织好模块,你可以把它们分组为包。当模块存储在文件.py中时,包就是模块所在的目录。
  为了让python将其作为包对待,它必须包含一个名为__init__.py的文件。
  如果要建立一个叫dd的包,其中包含aa和cc的模块,那么你就需要创建如下文件和目录:



1. D:/pythons
2. D:/pythons/dd
3. D:/python/sdd/__init__.py
4. D:/python/sdd/aa.py
5. D:/pythonsdd/cc.py
  (以上假设D:/pythons已经被放置到PYTHONPATH中。)



import dd             # __init__中的内容可用,aa和cc模块不可用
import dd.aa         #aa模块可用了,但只能使用全名dd.aa来使用
from dd import cc   #cc模块可用了,可用通过短名cc来使用
  
  三. 探究模块
  学会如何探究模块是极有价值的技能。探究模块最直接的方式是在python解释器中研究它们。
  3.1 模块中有什么 -- 比如copy标准模块
  (1)使用dir函数
  使用dir函数可以将对象的特性都列出,如下,我们可以使用列表推导式过滤掉一部分:



>>> import copy
>>>
['Error', 'PyStringMap', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']
>>>
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
  (2)继续查看它的__all__



>>> copy.__all__
['Error', 'copy', 'deepcopy']
  可见它定义了模块的公有借口,更准确地说,它告诉解释器:从模块导入所有名字代表什么含义。
  如:from cpy import *意味着你只能使用__all__变量中的几个函数,如果要导入PyStringMap的话,就要这样做:
  导入copy然后使用copy.PyStringMap;或者是使用from copy import PyStringMap
  我们在编写模块的时候,像设置__all__这样的技术是相当有用的,因为一个模块中可能会有一大堆其他程序不需要或者不想要的变量,函数和类,__all__会把它们过滤出去。如果没有设定__all__,用import*会默认输出模块中所有不以下划线开头的全局名称。
  
  3.2 用help函数获取帮助
  help函数能够为你提供日常所需的信息:



>>> help(copy)
Help on module copy:
NAME
copy - Generic (shallow and deep) copying operations.
FILE
c:\python27\lib\copy.py
DESCRIPTION
Interface summary:   
import copy
x = copy.copy(y)      # make a shallow copy of y
x = copy.deepcopy(y)    # make a deep copy of y
.......
  
  3.3 文档--模块信息的自然来源
  比如寻找range的文档描述:



>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns ; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns .The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
  这样就获得了关于range函数的精确描述。但是要记住,并不是所有的模块和函数都有不错的文档字符串的,有时候要透彻理解模块和函数是如何工作的,最好参考Pyhton库:http:python.org/doc/lib
  
  3.4 使用源代码
  使用如下语句就可以查找到想要模块的源代码位置:



>>> print copy.__file__
C:\Python27\lib\copy.pyc
  如果文件名以.pyc结尾,只要查看相应的以.py结尾的文件即可。
  
页: [1]
查看完整版本: python学习笔记之九:模块和包