第六章 常用模块(1):什么是模块,模块的导入及自定义模块

6.1 什么是模块

什么是模块? 模块简单点理解就是编程语言的工具包(包里有各种可用的方法,函数等), 导入模块我们就可以使用这些模块中的方法和函数了。

在计算机程序开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少, 很多编程语言都采用这种组织代码的方式。 在python中,最小一个.py文件就可以称之为一个模块(module),也可以是一个目录(directory)。

  • 模块的好处: + 提高代码的可维护性
    • 可重用。编写代码时可以调用已有的模块(这样可以节省很多代码量)
    • 可以避免函数名和变量名冲突(每个模块有独立的命名空间)
  • 模块的分类: + 标准模块(内置模块,标准库):python自带的,大概有300个。
    • 第三方模块:python社区里程序猿们写的模块,大概有18万个。需要自己安装(pip)
    • 自定义模块:自己写的。可以上传到python社区里。

help('modules') # 可以查询所有的本地模块,包括自己安装的 带下划线的模块都是本地调用的

6.2 模块的导入和自定义模块

6.2.1 函数的导入&调用

  • 函数导入的特点:
    • 程序里可以同时导入多个模块
    • 同一个模块重复导入时,只识别第一次

函数的导入语法有以下几种:

import module_name  # 导入名字为module_name的整个模块

from module_name import child_m1,child_m2  # 从名字为module_name的模块中的导入其子模块child_m1和child_m2

from module_name.xx.xx import child_m1  # 导入子模块中的模块用'.'

from module_name import child_m1 as m_1  # 给导入的模块起个别名m_1,以后使用的时候可以用别名调用

from module_name.xx.xx improt *  # 导入模块中的所有子模块不推荐使用!
# 因为导入的模块里有很多方法时,有可能会被程序中定义的同名的方法覆盖,而且不易排查。
  • 注意:
    • 模块一旦被导入(import),就相当于执行了该模块的py文件里的代码。
    • 模块导入时候python在哪找模块文件?
      • 用下面代码可以确认系统搜索模块的路径
      import sys
      sys.path  # 显示搜索模块的路径列表,依次搜索,找到就读取并停止继续搜索,没找到就报错。
      # 这个列表可以添加,不过退出程序后不会保存对列表的修改。

      执行结果windows:
      ['C:\\Users\\xxx\\Desktop\\python\\temp', 'C:\\Users\\xxx\\Desktop\\python', 'C:\\Program Files\\JetBrains\\PyCharm 2019.1.3\\helpers\\pycharm_display', 'C:\\Python37\\python37.zip', 'C:\\Python37\\DLLs', 'C:\\Python37\\lib', 'C:\\Python37', 'C:\\Users\\xxx\\AppData\\Roaming\\Python\\Python37\\site-packages', 'C:\\Python37\\lib\\site-packages', 'C:\\Program Files\\JetBrains\\PyCharm 2019.1.3\\helpers\\pycharm_matplotlib_backend']

      常用模块一般保存在‘site-packages’目录下

6.2.2 自定义模块

在python中,模块一旦被导入(import),就相当于执行了该模块的py文件里的代码。 >import模块:把导入的模块(导入时间点的)内容加载到内存中。

所以,在自定义模块里只定义函数,不需要写执行语句。因为写了会在import的时候执行。

下面我们用2个例子来介绍一下自定义模块的写法:

导入时被执行的例(错误例):

# 模块文件:module_test.py
def test_method():
    print('this is a test!')
    
test_method()
# import模块
import module_test  # 只是导入就会执行 module_test.py

执行结果:

this is a test!

一般自定义模块的例(正确例):

# 模块文件:module_test.py
def test_method():
    print('this is a test!')
# import模块
import module_test  # 只是导入就会执行 module_test.py
module_test.test_method()

执行结果:

this is a test!

6.2.3 常用模块-开元模块

为了方便世界上的工程师们共有自己的自定义模块,python官方提供了这么一个站点。
网址是:https://pypi.python.org/pypi 注册一个账号就可以上传自己的模块了。也可以下载一些进行学习。

安装模块,默认一般保存在‘site-packages’目录下,文件的扩展名是.egg

  • 安装方法有两种:
    • 手动安装,文件下载到本地,用build,install等命令手动安装。
    • 在线安装(或卸载),用pip(pip3)的命令安装

6.2.4 包(Package)

当你的模块文件越来越多,就需要对模块文件进行划分。比如把负责跟数据库交互的都放在一个文件夹,把与月面交互相关的放一个文件夹。

·
└── my_proj
    ├── crm  # 代码目录。
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py  # 入口程序。 -> 入口程序需要包同一级别才能导入
    └── proj  # 配置文件目录。
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsqi.py

向上面的crm和proj这样,一个文件夹管理多个模块文件,而且有初始化文件__init__.py的文件夹就被称为包。

init.py内可以写一些初始化的代码。导入包时就会执行。(一般都是空文件)
python3 中文件夹可以直接导入
python2 中目录中必须包含名为__init__.py的空文件(包初始化文件)才能导入。

1. 跨模块导入1

包之间的模块如何导入呢? 我们需要用入口程序(上例中的manage.py)来导入模块(官方推荐方式)

manage.py:

from crm import views

views.py:

from my_proj import settings

由于是从接口程序执行的命令。所以搜索路径包含了manage.py的目录,views.py的导入也会从这里开始搜索。

当我们想往views.py导入其他包下的模块可以吗?

from my_proj import settings

只要是通过入口程序执行的,就没问题。 因为之前我们讲过sys.path来确认包的搜索路径列表, 路径列表的第一个搜索路径就是执行文件(这里我们执行的是manage.py)的当前路径。

2. 跨模块导入2

当我们想直接执行views.py也可以调用其他包内的模块的时候, 我们可以手动对sys.path列表append一个路径。

注意:追加路径的时候要使用相对路径。不然执行环境改变会出现故障

python的当前路径怎么取得呢? 1. 在sys模块中的__file__变量就保存着执行文件对于执行路径的相对路径。

  1. 用os模块中的os.path.abspath(file)来获取当前的绝对路径。
  2. 然后用os模块中的os.path.dirname()方法取得上级目录名。

代码例views.py:

import sys
import os

BASE_DIR = os.path.dirname(os.path.dirname(sys.path.abspath(__file__)))  # 需要向上返回2级才能看到包

sys.path.append(BASE_DIR)  # 把路径添加到sys.path中。这个添加只在当次代码块执行中有效,执行结束后会重置列表。

from proj import settings  # 然后在下面面导入想到如的模块

这样我们直接执行views.py也可以导入其他的包了

3. 相对导入

我们可以用相对路径符号'.'来导入模块

  • 但是使用相对导入有以下两个条件:
    • 文件夹中必须有__init__.py文件,该文件可以为空,但是必须存在。(init.py 是让解释器把目录识别成包的初始化文件)
    • 不能作为顶层模块来执行该文件夹中的py文件(即 ..之后的路径,不能是入口程序所在的目录:程序根目录)

比如上面views.py的例,我们也可以有以下的写法。

代码例views.py:

from . import models  # 调用当前目录的models模块
from .. import settings  # ..回到了顶层目录,所以会报错

猜你喜欢

转载自www.cnblogs.com/py-xiaoqiang/p/11110845.html