Python 学习笔记 - 第四天

2018-07-04  本文已影响0人  罗佳欣

模块是包括 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, end=' ')
        a, b = b, a+b
    print()

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

导入模块:

>>> import fibo

使用模块:

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> 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

1.深入模块

使用 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

这种方式将会导入所有除了以下划线开头 _ 的命名. (不推荐)

1.1.作为脚本执行模块

使用这种方式运行 python 模块, 会直接执行模块中的代码:

python fibo.py <arguments>

此时, 模块名 __name__ 将被设置成 "__main__".
如果在模块中加入代码:

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

执行脚本:

$ python fibo.py 50
1 1 2 3 5 8 13 21 34

如果是直接导入该模块, 是不会执行这段代码的:

>>> import fibo
>>>

1.2.模块的搜索路径

搜索顺序:

  • 当前目录

  • 环境变量 PYTHONPATH 中的目录列表中搜索

  • Python 默认安装路径中搜索

  • 1.3."编译的" Python 文件

    为了加快加载模块的速度, Python 会在 __pycache_ 目录下缓存每个模块编译后的版本.
    module.version.pyc
    例如: CPython 3.3 版本中, spam.py 编译后的版本: __pycache__/spam.cpython-33.pyc.

    高级技巧:

  • 为了减少一个编译模块的大小, 可以在 Python 命令行中使用 -O 或者 -OO-O 删除所有断言语句, -OO 删除断言语句和 doc 字符串. 后缀为 .pyo

  • .pyc 和 .pyo 只是在加载模块的时候更快一些. 不会影响运行速度.

  • compileall 模块可以为指定目录中的所有模块创建 .pyc 或 .pyo (使用-O参数) 文件.

  • 2.标准模块

    Python 带有一个标准模块库, 并发布有独立的文档, 名为 Python 库参考手册.

    示例: 变量 sys.ps1 和 sys.ps2 定义了主题师傅和辅助提示符:

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

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

    操作修改 sys.path :

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

    3.dir() 函数

    内置函数 dir() 获取模块中的所有模块定义:

    >>> import fibo, sys
    >>> dir(fibo)
    ['__name__', 'fib', 'fib2']
    >>> dir(sys)  
    ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
     '__package__', '__stderr__', '__stdin__', '__stdout__',
     '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
     '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
     'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
     'call_tracing', 'callstats', 'copyright', 'displayhook',
     'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
     'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
     'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
     'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
     'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
     'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
     'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
     'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
     'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
     'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
     'thread_info', 'version', 'version_info', 'warnoptions']

    不传参数时, 返回当前定义的命名:

    >>> a = [1, 2, 3, 4, 5]
    >>> import fibo
    >>> fib = fibo.fib
    >>> dir()
    ['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']

    dir() 不会列出内置函数和变量名.
    但是可以通过列出标准模块 builtins 来查看:

    >>> import builtins
    >>> dir(builtins)  
    ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
     'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
     'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
     'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
     'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
     'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
     'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
     'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
     'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
     'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
     'NotImplementedError', 'OSError', 'OverflowError',
     'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
     'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
     'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
     'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
     'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
     'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
     'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
     '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
     'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
     'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
     'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
     'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
     'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
     'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
     'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
     'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
     'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
     'zip']

    4.包

    示例一个处理声音的模块集:

    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
                  ...

    包目录中必须包含 __init__.py 文件.

    可以每次只导入包里的特定模块:

    import sound.effects.echo

    使用时需要通过完整的名称来引用:

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

    或者加载子模块

    from sound.effects import echo

    调用时:

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

    或者只加载子模块的一个命名:

    from sound.effects.echo import echofilter

    调用时:

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

    使用 from package import item 时, item 可以是包/模块/命名.
    使用 import item.subitem.subsubitem 时, 最后的子项可以是包/模块, 但不能是前一个子项的类/函数/变量.

    4.1.从 * 导入包.

    如果包中的 __init__.py 中定义了一个名为 __all__ 的列表, 就会按照列表中给出的模块名进行导入.
    示例: 在 sound/effects/__init__.py 文件中:

    __all__ = ["echo", "surround", "reverse"]

    当使用 from sound.effects import * 导入这个包时, 会从 sound 包中导入这三个子模块.
    如果没定义 __all__, 将不会导入所有子模块.

    但是, 不推荐使用 * 的方式去导入模块命名!!!

    4.2.包内引用

    如果包内使用了子包结构, 可以按绝对位置从相邻的包中引入子模块.
    例如: 如果 sound.filters.vocoder 包需要使用 sound.effects 包中的 echo 模块, 它可以 from sound.Effects import echo.

    也可以使用点号标明关联导入当前包和上级包.
    示例:

    from . import echo
    from .. import formats
    from ..filters import equalizer

    4.3.多重目录中的包

    包支持一个更为特殊的特性, __path__. 在包的 __init__.py 文件代码执行之前, 该变量初始化一个目录名列表. 该变量可以修改, 它作用于包中的子包和模块的搜索功能.

    这个功能可以用于扩展包中的模块集, 不过它不常用.

    上一篇下一篇

    猜你喜欢

    热点阅读