模块与包&相对绝对路径

发布时间 2023-12-15 09:04:35作者: ssrheart

【一】模块与包

(1)什么是模块

  • 在Python中,一个py文件就是一个模块,文件名为xxx.py模块名则是xxx,导入模块可以引用模块中已经写好的功能。

(2)模块的来源

  • 内置的:python解释器自带的,直接拿来使用的
  • 第三方的:别人写的,如果想用,就要先下载在使用
  • 自定义的:我们自己写的

(3)模块的存在形式

  • 我们自己写的py文件(一个py文件就是一个模块)
  • 包:一系列py文件的集合(文件夹)

一个包里面会有一个__init__.py文件

(4)模块的使用

(1)直接导入

  • import 语句
import py文件名/模块名

(2)import导入多个模块方式

  • 用import语句导入多个模块

    • 可以写多行import语句
    import module1
    import module2
        ...
    import moduleN
    
  • 还可以在一行导入,用逗号分隔开不同的模块

    import module1,module2,...,moduleN
    

但其实第一种形式更为规范,可读性更强,推荐使用

而且我们导入的模块中可能包含有python内置的模块、第三方的模块、自定义的模块

为了便于明显地区分它们,我们通常在文件的开头导入模块

并且分类导入

一类模块的导入与另外一类的导入用空行隔开

(5)详细导入

  • from ... import ... 语句
from 模块位置 import 模块名

(6)模块重命名

  • from ... import ... as ... 语句
from 模块位置 import 模块名 as 自定义名字
  • 我们还可以在当前位置为导入的模块起一个别名
#为导入的模块foo在当前位置起别名f,以后再使用时就用这个别名f
import foo as f 
f.x
f.get()
  • 通常在被导入的名字过长时采用起别名的方式来精简代码
    • 另外为被导入的名字起别名可以很好地避免与当前名字发生冲突
  • 还有很重要的一点就是:
    • 可以保持调用方式的一致性
  • 例如
    • 我们有两个模块json和pickle同时实现了load方法
      • 作用是从一个打开的文件中解析出结构化的数据
    • 但解析的格式不同
      • 可以用下述代码有选择性地加载不同的模块
if data_format == 'json':
    # 如果数据格式是json,那么导入json模块并命名为serialize
    import json as serialize 
elif data_format == 'pickle':
    # 如果数据格式是pickle,那么导入pickle模块并命名为serialize
    import pickle as serialize 
    
# 最终调用的方式是一致的
data=serialize.load(fn) 

【二】包

(1)什么是包

  • 包是一个模块的集合,它可以将多个模块的功能组合到一起。
  • 包可以按照其功能和作用进行分类,方便用户查找和使用。
  • 包是在Python标准库中定义的一种特殊类型的模块,可以通过import语句来引入和使用。
  • Python的包分为标准库包和第三方库包。
    • 标准库包是Python内置的包,包含了一些基本的模块和函数,如os、sys、random等;
    • 第三方库包是第三方开发的包,通常提供了更加丰富和高级的功能。

(2)包结构

  • 包是Python程序中用于组织模块的一种方式。包是一个包含模块的目录,同时还可以包含其他子包。
  • 要创建一个包,我们只需要在目录中创建一个名为__init__.py的文件即可。
|-pakageName
	|-__init__.py
	|-moduleName1.py
	|-moduleName2.py
	|-...
  • 包路径下必须存在 __init__.py 文件。

(3)创建包

  • 我们创建一个 cal 的包,包中有一个计算器的 model ,结构如下:
|-cal
	|-__init__.py
	|-calculator.py
  • calculator.py
def add(a, b):
    return a + b


def reduce(a, b):
    return a - b


def multiply(a, b):
    return a * b


def divide(a, b):
    return a / b

(4)直接使用包

  • Python 包的使用和模块的使用类似,下面是导入的语法:
import 包名.包名.模块名

(1)演示

  • 比如我们在 use_cal.py 中导入 calculator.py
# 导入包
import cal.calculator
# 使用包的模块的方法
print(cal.calculator.add(1,2))

image

(2)详细使用包

from 包名.模块名 import 模块中的方法

(5)制作包

(1)注册包

  • 在cal包下的__init__.py中注册相关变量
from .calculator import add, reduce

(2)使用包

from cal import add, reduce

【三】循环导入问题

  • 循环导入问题指的是在一个模块加载/导入的过程中导入另外一个模块
    • 而在另外一个模块中又返回来导入第一个模块中的名字
  • 由于第一个模块尚未加载完毕
    • 所以引用失败、抛出异常
  • 究其根源就是在python中
    • 同一个模块只会在第一次导入时执行其内部代码
    • 再次导入该模块时
    • 即便是该模块尚未完全加载完毕也不会去重复执行内部代码
  • 解决方式:导入语句放到最后,保证在导入时,所有名字都已经加载过

【四】相对路径和绝对路径

(1)绝对路径

  • 从最根本的盘符开始找起来的文件路径
D:\2023propygo\day\day15\ATM1.py

(2)相对路径

  • 是相较于当前文件存在的文件夹开始找起来的
r'无参装饰器练习.py'