zoukankan      html  css  js  c++  java
  • 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
    >>> [n for n in dir(copy) if not n.startswith('_')]
    ['Error', 'PyStringMap', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']
    >>> [n for n in dir(copy) if n.startswith('__')]
    ['__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:python27libcopy.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 [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
    When step is given, it specifies the increment (or decrement).
    For example, range(4) returns [0, 1, 2, 3].  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:Python27libcopy.pyc

    如果文件名以.pyc结尾,只要查看相应的以.py结尾的文件即可。

  • 相关阅读:
    Linux进程间通信之信号量
    C语言文件操作
    Linux多线程同步方法
    Linux进程间通信之共享内存
    关于P2P下载的思考
    学习Jxta,初窥门径
    庆祝一下,基于JXTA的P2P文件共享传输文件测试成功。
    关于java nio在windows下实现
    Java aio和JSR 203
    关于文件目录的P2P共享问题
  • 原文地址:https://www.cnblogs.com/bangbangjiang/p/3418077.html
Copyright © 2011-2022 走看看