包和模块

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

1. 模块

1.1 概念

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

模块是一个包含 Python 定义和语句的文件。文件名就是模块名后跟文件后缀 .py

案例:

使用你最喜欢的文本编辑器(当然不建议 windows 记事本)在当前目录下创建一个名为 fibo.py 的文件,文件中含有以下内容。

# 斐波那契数列 模块

def fib(n):    # 打印斐波那契数列到数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

1.2 导入模块

通过关键字 import 可以在代码中导入写好的模块,语法如下:

import 模块名

案例:

现在进入解释器,并用以下代码导入 fibo.py

import fibo

在当前变量表中,不会直接定义模块中的函数名,它只是定义了模块名。接下来,通过模块名 fibo 就可以访问其中的函数

fibo.fib(10)
fibo.fib2(10)

0 1 1 2 3 5 8

[0, 1, 1, 2, 3, 5, 8]
import 语句有一个变体,它可以把模块中的名称(函数名,变量,类名)直接导入到当前模块的变量表里,语法如下:

from 模块名 import 名称

案例:

from fibo import fib, fib2

这并不会把被调模块名引入到当前变量表里,而是将函数名 fib,fib2 引入,现在可以直接访问这两个函数了。

fib(10)
fib2(10)

0 1 1 2 3 5 8

[0, 1, 1, 2, 3, 5, 8]
还有一个变体可以导入模块中定义的所有名称,语法如下:

from 模块名 import *

这会导入所有非以下划线(_)开头的名称。 在多数情况下,Python 程序员都不会使用这个功能,因为它在解释器中引入了一组未知的名称,而它们很可能会覆盖一些你已经定义过的东西。

注意通常情况下从一个模块或者包内导入 * 的做法是不太被接受的, 因为这通常会导致代码的可读性很差。不过,在交互式编译器中为了节省打字可以这么用。

如果模块名称之后带有 as,则跟在 as 之后的名称将直接绑定到所导入的模块。语法如下:

import 模块名称 as 新名称
from 模块名称 import 名称 as 新名称
案例:
# 取别名的场景:导入的定义名称与当前的名称冲突了,或导入的定义名称太长了。
import fibo as fib
fib.fib(10)

0 1 1 2 3 5 8
这会和 import fibo 方式一样有效地调入模块, 唯一的区别是它以 fib 的名称存在的。

这种方式也可以在用到 from 的时候使用,并会有类似的效果:

from fibo import fib as fibonacci
fibonacci(10)

0 1 1 2 3 5 8
注意:出于效率的考虑,每个模块在解释器会话中只被导入一次。

2. 包

2.1 概念

模块的问题解决了代码过长不便于维护问题,但是如果不同人编写的模块名相同怎么办?为了避免模块名冲突,python 又引入了用目录来组织模块的方法,称为包。

为了避免 fibo.py 与其他模块冲突,我们可以选择一个顶层包名,例如:my_fibo,然后创建名为 my_fibo 的文件夹,将模块 fibo.py 放入该文件夹下。然后通过 import 包名.模块名 的方式引入,只要顶层包名不起冲突,模块就不会起冲突。现在 fibo 模块的引入就是这样的:

import my_fibo.fibo

但是这样导入引用时也要用全名

my_fibo.fibo.fib(10)

0 1 1 2 3 5 8
也可以通过结合 from 引用

from my_fibo import fibo

这样可以是用 fibo 调用模块中的函数

fibo.fib(10)

0 1 1 2 3 5 8
也可以直接导入所需的函数或变量

from my_fibo.fibo import fib

这样可以直接调用 fib 函数

fib(10)

0 1 1 2 3 5 8
请注意,当使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量。 import 语句首先测试是否在包中定义了 item;如果没有,它假定它是一个模块并尝试加载它。如果找不到它,则引发 ImportError 异常。

相反,当使用 import item.subitem.subsubitem 这样的语法时,除了最后一项之外的每一项都必须是一个包;最后一项可以是模块或包,但不能是前一项中定义的类或函数或变量。

注意每一个包根目录下都有一个 __init__.py 的文件,这个文件必须存在,因为 python 就是通过它来区分普通文件夹和包。__init__.py

3.第三方库

作为一个受欢迎的开源开发项目,Python 拥有活跃的贡献者和用户支持社区,并且根据开放源代码许可条款,其软件可供其他 Python 开发人员使用。

这使 Python 用户可以受益于其他人已经针对常见(有时甚至是罕见的)问题创建的解决方案,并可以有效地共享和协作,并有可能将自己的解决方案贡献给公共资源库。

其他用户共享在公共资源库中的 python 项目就是第三方库。

换句话说就是别人写的 python 模块。

3.1 pip

有很多方法可以管理 python 的第三方库,推荐使用 pip 下载,安装,删除第三方库。

从 Python 3.4 开始,它默认包含在 Python 二进制安装程序中。

命令行中输入一下命令来安装模块的最新版本和依赖项:

pip install SomePackage

3.2 pip 源的配置

应为 pip 会从网上下载模块,默认服务器在国外,可以配置将 pip 源服务配置为国内的镜像服务器。

国内比较稳定优质的镜像:

清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
豆瓣:http://pypi.douban.com/simple/

3.2.1 临时配置

通过在安装命令后加上-i 参数手动临时指定源

pip install requests -i https://pypi.doubanio.com/simple

3.2.2 永久配置

通过修改 pip 的配置文件,以后运行 pip 命令会使用配置中的源。

windows 平台配置
  1. 新建 pip 配置文件夹,直接在 user 用户目录中创建一个名为 pip 的文件夹( 即 %HOMEPATH%\pip),如下图所示:
  1. 接着在 pip 文件夹中创建一个名为 pip 的文本文件(后缀名由" .txt "改为 " .ini "),格式如下所示:

文件内容如下:

[global]
index-url = https://pypi.doubanio.com/simple
[install]
trusted-host = https://pypi.doubanio.com/  

保存后重新打开命令行工具使用 pip 安装第三方库就会使用配置的源。

liux/mac 平台配置
  1. 在家目录下创建 pip 配置文件夹 .pip
cd ~ # 切换到家目录

mkdir .pip # 创建配置文件夹

  1. 创建配置文件

cd .pip # 切换到配置文件夹下

vim pip.conf # 创建并编辑配置文件

文件内容如下:

[global]
index-url = https://pypi.doubanio.com/simple
[install]
trusted-host = https://pypi.doubanio.com/  

保存后重新打开终端使用 pip 安装第三方库就会使用配置的源。