Python学习之模块与包的导入

前言

问题

为什么存在导入语句?

python能够使用import语句导入哪些东西?

导入时出现ModuleNotFoundError: No module named 'xxx'错误的原因,导入的模块的路径查找顺序?

导入语句的几种形式及注意点

sys模块与导入路径关系

__init__.py文件的作用

if __name__=='__main__':的使用

预备知识

包、模块的概念

重点

导入语句格式及注意点

推荐的导入方式

1. 导入语句的必要性

模块复用——-减少代码冗余、提高开发效率

2. 导入的对象

  • 模块文件(.py文件)
    • 导入整个文件
    • 导入变量
    • 导入函数
    • 导入类
  • C或C++扩展(已编译为共享库或DLL文件)
  • 包(包含多个模块,一定包含__init__.py文件)
  • 内建模块(使用C编写并已链接到Python解释器中)

3. 模块的搜索路径

出现ModuleNotFoundError: No module named 'xxx'问题一定是因为在sys.path返回的所有路径中搜索不到模块的名字

sys.path指定了模块的搜索路径的字符串列表。sys模块包含了与python解释器和它的环境有关的函数, 里面有个 sys.path属性。它是一个list.默然情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话,程序就会报错。

通过sys.path指定了模块的搜索路径的字符串列表。

sys.path.append()方法添加模块的搜索路径,sys.path作用域只是当前进程,进程结束后就失效了。

例:sys.path.append('')将当前路径加入到模块的搜索路径

3.1 模块的搜索路径的组成

Python搜索模块的路径是由四部分构成的:程序的主目录、PATHONPATH目录、标准链接库目录和.pth文件的目录,这四部分的路径都存储在sys.path 列表中。

1,程序的主目录

主目录是指包含程序的顶层脚本的目录,Python首先会到主目录中搜索模块。

因为主目录总是第一个被搜索,如果模块完全处于主目录中,所有的导入都会自动完成,而不需要单独配置路径。

2,PATHONPATH目录

PATHONPATH目录是指PATHONPATH环境变量中配置的目录,是第二个被搜索的目录,Python会从左到右搜索PATHONPATH环境变量中设置的所有目录。

3,标准链接库目录

标准链接库目录是Python按照标准模块的目录,是在安装Python时自动创建的目录,通常不需要添加到PYTHONPATH目录中。

4,路径文件(.pth文件)

在模块搜索目录中,创建路径文件,后缀名为.pth,该文件每一行都是一个有效的目录。Python会读取路径文件中的内容,每行都作为一个有效的目录,加载到模块搜索路径列表中。简而言之,当路径文件存放到搜索路径中时,其作用和PYT)HONPATH环境变量的作用相同。

如果运行在Windows和Python3.0中,如果Python安装目录的顶层是C:\Python30,那么可以把自定义的路径文件 mypath.pth 放到该目录中。

也可以放到标准库所在位置的sitepackages子目录中(C:\Python30\Lib\sitepackages),来扩展模块的搜搜路径。

3.2 设置模块的搜索路径

上述四种模块搜索路径,能够配置的选项只有PYTHONPATH环境变量和路径文件。

  • 例如,在Windows平台上,创建PYTHONPATH环境变量,设置变量的值,两个目录使用分号隔开:
C:\pycode\utilities;D:\pycode\package1
  • 也可以创建一个名为 C:\Python30\pydirs.pth的文本文件,其内容如下所示:
C:\pycode\utilities
D:\pycode\package1
  • sys.path.append(absolute_or_relative_path_string)将当前路径加入到模块的搜索路径,一般在代码编写的最前面———————————————————-推荐

__init__.py的主要作用

  1. Python中package的标识,不能删除

  2. 定义__all__用来模糊导入

  3. 编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单)

__init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件。

通常__init__.py 文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__init__.py文件。这样我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。

4. 导入语句

4.1 导入模块

导入语法

  1. 导入整个模块(.py文件)

    格式1:import module_name

    格式2:import package_name.module_name 当模块在某个包内

  2. 导入某个模块的类(变量与函数类似)

    格式1:import module_name.class_name

    格式2:from package_name.module_name import class_name

    格式3:import package_name.module_name.class_name 当类所在模块模块在某个包内

    格式4:from package_name.module_nameimport class_name 当类所在模块模块在某个包内

if __name__=='__main__':的使用

  • if name == ‘main‘ 我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。
  • 作用
    • 作为模块测试—–测试当前.py文件的功能
  • if __name__==__main__:如果模块是被导入的,则代码块不被运行的原因
    • 在当前模块直接执行print(__name__)的结果永远是:__main__
    • 在当前模块被别的模块import导入执行时__name__结果是:[包名.]模块名
    • if判断__name__不等于__main__,故不执行其下的代码,导入时执行了判断,只是不符合条件

查看导入的模块的路径

语句:module_name.__file__

如:

import random

random.__file__

需要说明的是,并不是所有模块都是使用 Python 语言编写的,有些与底层交互的模块可能是用 C 语言编写的,而且是 C 程序编译之后的效果,因此这种模块可能没有 file 属性,如sys模块。

4.2 导入包

格式1:import package_name 导入包下的__init__.py文件

(1)如果包下的__init__.py文件没有写任何语句,是一个空文件,这种格式无法调用任何包内的模块

例子:

文件

# my_package_1包下的__init__.py文件
# my_package_1包下的test01.py文件
def my_test_1():
    print('这里是my_package_1包下的test01.py文件')
# my_import_package_1.py文件
import my_package_1
my_package_1.test01.my_test_1()

输出:

AttributeError: module 'my_package_1' has no attribute 'my_test_1'

原因:

__init__.py是一个空文件,使用import package_name该种导入方式无法使用包中的模块,保证__init__.py导入模块写了import 导入语句(建议和__all__连用,但是单独只有__all__无法找到模块)

(2)如果包下的__init__.py文件写了导入语句

例子:

# my_package_2包下的__init__.py文件
from . import test02
#__all__=['test02']
# my_package_2包下的test02.py文件
def my_test_2():
    print('这里是my_package_2包下的test02.py文件')
# my_import_package_2.py文件
import my_package_2
my_package_1.test02.my_test_2()

输出:

这里是my_package_2包下的test01.py文件

原因:

__init__.py是一个空文件,使用import package_name该种导入方式无法使用包中的模块,保证__init__.py导入模块写了导入语句或给__all__赋值

建议:__init__.py导入模块写import 导入语句(建议和__all__连用,但是单独只写__all__不写导入语句无法找到模块)

格式2:from package_name import module_name——-推荐

(1)对包下的__init__.py文件没有要求,这种格式直接调用任何包内的某个模块

例子:

文件

# my_package_3包下的__init__.py文件
# my_package_3包下的test03.py文件
def my_test_3():
    print('这里是my_package_3包下的test03.py文件')
# my_import_package_3.py文件
from my_package_3 import test03    #**********************************************
test03.my_test_3()

输出:

print('这里是my_package_3包下的test03.py文件')

格式3:from package_name import *

from package_name import *调用时不需要写包名,引入过多有命名冲突问题

from package_name import *导入的是

  • 所有在__init__.py文件中__all__列表变量的内容

  • __init__.py文件中import导入的模块

  • __all__列表与import导入同时使用,以__all__列表为准

  • 同格式1:import package_name,需要保证__init__.py有被调用的导入模块

问题

什么是内建模块?module ‘sys’ < built-in > is a built-in module,与普通的模块区别?为什么嵌入式版本python模块搜寻路径没有当前路径?

__init__.py可以写哪些内容?作用是什么?有什么书写建议或规范?

相对导入与绝对导入问题

参考文章

1.【Python】 sys.path(环境变量)与init.pyhttps://blog.csdn.net/v_xchen_v/article/details/80393967)

2.Python 学习 第13篇:模块搜索路径和包导入https://www.cnblogs.com/ljhdo/p/10674242.html)


   转载规则


《Python学习之模块与包的导入》 WangWei 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
Python学习之Python编程规范 Python学习之Python编程规范
前言问题为什么Python编程需要规范? 规范的要求有那几个方面? 不规范的后果有哪些? 书写规范的标准 命名规范1.标识符命名规则 以字母、下划线、数字组成,且不能以数字开头 不能是关键字与保留字 注:python3标识符可以存在汉字,不
下一篇 
Python环境安装 Python环境安装
软件安装下载地址Python官网安装地址 : https://www.python.org/downloads 以安装Python 3.7.4为例 安装包选项安装包选项如下: Version Operating System Descr
2019-07-22 WangWei
  目录