Python学习笔记 模块和包

目录

 关于模块

 关于包

 相对导入和绝对导入

关于模块

  • py文件的两种用途
    1、脚本,程序文件,用来被执行
    2、模块,功能文件,用来被引用

PS:脚本的全局变量__name__ == '__ main__ ',模块的__name__ == 模块名

  • 模块的分类(4种)
    1、 使用Python编写的 .py文件
    2、 已经被编译为共享库或DLL或C++扩展
    3、 把一系列模块组织到一起的文件夹,即包
    4、 使用C编写并连接到Python解释器的内置模块
  • 模块的导入
import 模块1,模块2from 模块 import 方法
直接把模块中的名字导入当前命名空间
from 模块 import *
把模块中所有不是以(_)开头的成员导入该命名空间,如果__all__(一个列表)不为空,则导入其中包含的成员(一般不用,可读性太差)
fromimport 模块  
fromimport 模块 as 别名
  • 模块导入时的行为(3步)
    1、为源文件(模块文件)创建新的命名空间。在导入模块中定义的函数和方法若是使用到了被导入模块时,访问的就是这个命名空间
    2、在创建新命名空间时执行模块中包含的代码。只会在第一次导入时执行。Python为了防止模块的重复导入,它会在第一次导入时将模块加载到内存中,除第一次外的导入都是对已加载到内存中的模快对象的引用,不会重复执行模块内的语句。这样可以避免模块中代码重复执行造成的时间和资源浪费
    3、创建名字(即模块名)来引用该命名空间。

PS:可以从sys.module中查看已加载的模块。sys.module是一个包含模块名和模块对象的字典。该字典决定模块是否需要被重新导入

  • 关于命名空间
    如student.age;student就是一个命名空间。student.age表示对象age属于student命名空间,与该命名空间之外的同名对象不发生冲突。

  • 模块搜索路径
    内存中已加载的模块 ——> 内置模块 ——> sys.path路径(可修改)包含的模块

PS: Python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules(一个字典)查看,sys.path是一个列表,其中每个元素都是模块的搜索路径,可以向里面插入你想搜索的路径。

关于包

  • 包的本质
    包就是一个含有__init__.py文件的文件夹,它存在的意义就是将文件/模块组织起来,方便管理和重用。其实包的本质和模块是一样的,创建包的目的是为了引用。模块为其属性和方法提供一个命名空间,而包为其模块和子包提供命名空间。

PS:即使包下没有包含__init__.py文件,程序也不会报错(在Python3不报错,Python2下必须有这个文件)

  • 包的__init__.py文件
    个人感觉它与类中的__init__方法性质颇为相似,都是属于那种做初始化工作的部分。当导入一个包时,__init __.py(如果有)就会被自动执行(不像包中的其他模块,只有被导入时才执行)。属性__all __常在__init __.py中定义,这个列表可以控制 * 导入的内容,如from package import * ,这里并不会导入package中的所有模块,而是只导入__all __列表中有的模块,如__all __为空,那么该语句就只会导入__init __.py文件(模块)
  • 包的导入
import# 这种方法不会导入包中所有的子模块,只会导入__init__.py和__all__中包含的模块
fromimport 模块
# 这里明确import的后面是一个模块或属性方法,一个点都不能带

PS:导入时,无论在什么位置使用 '. '符号,它的左边必须是一个包,否则非法。

相对导入和绝对导入

  相对导入和绝对导入的概念是对于包内导入而言的,也就是说,只有包内模块之间的相互导入才有相对导入和绝对导入的概念。相对导入要保证执行导入的模块必须有包结构(必须在一个包的内部),该模块只能导入其顶级包内部的模块。如果在顶级包外使用相对导入,会报错。

  以下图的包结构讨论绝对导入和相对导入
在这里插入图片描述

  • 绝对导入
    绝对导入就是以顶级包为起点开始导入(在上面的包结构中,PackageA为顶级包),例如下
# 我们在fun3中导入fun5:
from PackageA.PackageC import fun5
# 或
import PackageA.PackageC.fun5

  绝对导入的好处就是它在执行文件和被导入的模块中都可以使用,但是就是有点麻烦,每次都要从顶级模块开始,而
  且一旦上层包的名字改变了,那么导入就会出。

  • 隐式相对导入
    隐式相对导入是相对导入的一种,就是在没有告诉解释器相对于谁进行导入的情况下导入模块(默认是相对于当前模块),由于这种导入方式强烈不推荐,所以不过多赘述。例如下
import fun2
# 在fun1中导入fun2模块
  • 显式相对导入
    显式相对导入需要使用 '. '符号。它也是相对于导入语句所在的模块文件,但是 '. '符号数量不同表示的含义也不同
    比如
from . import fun4
# 在fun3中导入fun4模块
from .. import fun5
# 在fun3导入fun5模块

  . 代表模块文件所在的文件夹,即模块文件的上一级文件(例中的PackageB)
  … 代表模块文件所在文件夹的上一级文件夹(例中的PackageA)
  总结:相对于当前模块,多一个点就往上推一级

PS:如果直接运行含有显式相对导入语句的模块,会报错。因为在没有明确指定包结构的情况下,Python会根据__name__属性来决定一个模块在包中的结构,如果模块的__name__属性值为__main__即__name__ == ’main’,则该模块本身就是顶级模块,没有包结构。顶级模块不存在层次结构,也就找不到其他的相对路径,所以会报错。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值