zoukankan      html  css  js  c++  java
  • python笔记-模块和包

    一、什么是模块

      如果你从Python解释器退出并再次进入,之前的定义(函数和变量)都会丢失。因此,如果你想编写一个稍长些的程序,最好使用文本编辑器为解释器准备输入并将该文件作为输入运行。这被称作编写 脚本 。随着程序变得越来越长,你或许会想把它拆分成几个文件,以方便维护。你亦或想在不同的程序中使用一个便捷的函数, 而不必把这个函数复制到每一个程序中去。

      为支持这些,Python有一种方法可以把定义放在一个文件里,并在脚本或解释器的交互式实例中使用它们。这样的文件被称作 模块 ;模块中的定义可以 导入 到其它模块或者 主模块(你在顶级和计算器模式下执行的脚本中可以访问的变量集合)

      模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀 .py 。在一个模块内部,模块名(作为一个字符串)可以通过全局变量 __name__ 的值获得

    二、模块编写与使用

    使用文本编辑器在当前目录下创建一个名为 fibo.py 的文件, 键入以下代码

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

    使用模块中的函数
    现在进入Python解释器,并用以下命令导入该模块:

    >>> import fibo
    

    在当前的符号表中,这并不会直接进入到定义在 fibo 函数内的名称;它只是进入到模块名 fibo 中。你可以用模块名访问这些函数

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

    如果你想经常使用某个函数,你可以把它赋值给一个局部变量

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

    三、模块导入方法

    1. import 模块名
    2. from 模块名 import 模块中的属性
    >>> from fibo import fib, fib2
    >>> fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
    
    1. import 模块名 as 新模块名
    >>> import fibo as fib
    >>> fib.fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
    
    1. from 模块名 import 模块中的属性 as 新属性名
    >>> from fibo import fib as fibonacci
    >>> fibonacci(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
    

    注意:

    1. 出于效率的考虑,每个模块在每个解释器会话中只被导入一次。
    2. 因此,如果你更改了你的模块,则必须重新启动解释器, 或者,如果它只是一个要交互式地测试的模块,请使用 importlib.reload(),例如 import importlib; importlib.reload(modulename)

    四、脚本方式执行模块

    模块里的代码会被执行,就好像你导入了模块一样,但是 __name__ 被赋值为 "__main__"。 这意味着通过在你的模块末尾添加这些代码

    if __name__ == "__main__":
        import sys
        fib(int(sys.argv[1]))
    
    1. 如果模块是被导入的,这些代码是不运行的

    五、模块搜索路径

    1. 当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的内置模块
    2. 如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找名为 spam.py 的文件

    sys.path包含的路径

    1. 包含输入脚本的目录(或者未指定文件时的当前目录)
    2. PYTHONPATH (一个包含目录名称的列表,它和shell变量 PATH 有一样的语法)
    3. 取决于安装的默认设置

    六、编译过的python模块

    为了加速模块载入,Python在 __pycache__ 目录里缓存了每个模块的编译后版本,名称为 module.version.pyc ,其中名称中的版本字段对编译文件的格式进行编码; 它一般使用Python版本号。例如,在CPython版本3.3中,spam.py的编译版本将被缓存为 __pycache__/spam.cpython-33.pyc。此命名约定允许来自不同发行版和不同版本的Python的已编译模块共存。

    Python根据编译版本检查源的修改日期,以查看它是否已过期并需要重新编译。这是一个完全自动化的过程。此外,编译的模块与平台无关,因此可以在具有不同体系结构的系统之间共享相同的库。

    Python在两种情况下不会检查缓存。首先,对于从命令行直接载入的模块,它从来都是重新编译并且不存储编译结果;其次,如果没有源模块,它不会检查缓存。为了支持无源文件(仅编译)发行版本, 编译模块必须是在源目录下,并且绝对不能有源模块。

    七、包

    包是一种通过用“带点号的模块名”来构造 Python 模块命名空间的方法。 例如,模块名 A.B 表示 A 包中名为 B 的子模块

    例如, 处理声音包

    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__ 变量

    7.1 包的导入

    1. 导入包的单个模块
    import sound.effects.echo
    
    • 这会加载子模块 sound.effects.echo 。但引用它时必须使用它的全名
    sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
    
    1. 导入包的子模块
    from sound.effects import echo
    
    1. 直接导入所需的函数或变量
    from sound.effects.echo import echofilter
    

    当使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量

    1. form package import *: 会导入包__init__.py中的__all__列表变量包含的所有模块

    2. 相对路径导入

    from . import echo
    from .. import formats
    from ..filters import equalizer
    
    • 请注意,相对导入是基于当前模块的名称进行导入的。由于主模块的名称总是 "main" ,因此用作Python应用程序主模块的模块必须始终使用绝对导入。
  • 相关阅读:
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 C: Coconut
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 A: Banana
    第2周项目1c++语言中函数参数传递的三种方式
    第2周项目2程序的多文件组织
    【BZOJ 3224】普通平衡树
    【POJ 1741】Tree
    浅谈树分治
    【luogu 2709 / BZOJ 3781】小B的询问
    【luogu 1972 / BZOJ 1878】HH的项链
    【BZOJ 3339 / BZOJ 3585 / luogu 4137】Rmq Problem / mex
  • 原文地址:https://www.cnblogs.com/duyupeng/p/13168273.html
Copyright © 2011-2022 走看看