模块的概念与使用
调包侠之Python模块
-
索引取值和迭代取值的差异
-
模块简介
-
导入模块的两种句式
-
导入模块句式补充
-
循环导入问题解决策略
-
判断文件类型
-
模块的查找顺序
-
模块的绝对导入和相对导入
-
包的概念
-
索引取值和迭代取值的差异
两者的使用主要是应用在不同的应用场景
- 索引取值
- 索引取值可以在不同的位置反复的取值
- 不支持无序类型的取值
- 迭代取值
- 只能重前往后取值且无法后退
- 支持对无序数据取值
- 模块介绍
- 模块的本质就是内部具有一定功能的py文件
- python的黑历史,在刚开始不火的时候被人戏称为调包侠,随着越来越多的程序员加入,先在看到python都要称一声调包侠
- python模块的表现形式
- python文件也可以称为模块文件
- 包含多个python文件的文件夹被称为包,(python2中的包文件具有__init__.py文件)
- 已经编译为共享库或DLL的c或者C++扩展
- 使用C编写并链接到python解释器的内置模块
- 模块分类
- 自定义模块
自定义模块就是程序员自己写的py文件 - 内置模块
python解释器自带的模块 - 第三方模块
由一些开发者大佬写的模块,我们可以直接使用pip安装并调用
- 导入模块的两种句式
注意: 这里一定要注意谁是被执行文件
- import modular_name
- from modular_name import parameter
1. import modular_name
"""
使用import导入模块的原理
案例: 现在run.py作为被执行文件需要导入同级目录下的register.py并调用其中的userinfo列表,代码如下:
# run.py # 作为被执行文件
import register
print(register.userinfo)
# register.py # 作为模块
userinfo = ['wesley', 'otheruser']
def register():
"""注册用户"""
pass
1. 被执行文件run运行,创建名称空间
2. 执行import register 加载模块文件,并创建模块文件的名称空间
3. 执行文件执行print(register.userinfo),对应模块文件的userinfo
4. 执行print(register.userinfo)可以调用到模块中用户的数据
"""
2. from modular_name import parameter
# 这里还是以上面的代码为例:
"""
1. 执行文件run执行创建名称空间,并执行from register import userinfo # 这个parameter这里和是用import不同的是可以写模块中的变量,如果不知道变量名叫什么可以写※号,※号代表加载所有的变量名
2. 执行from register import userinfo 后会创建模块的名称空间,并创建所有的变量名,与上面不同的是,由于我们值from了一个userinfo所以被执行文件这里只会讲userinfo的变量名与模块中的变量名绑定,其他的变量名无法调用
"""
- import parameter 和 from modular_name import parameter的优缺点
- import parameter
优点:在调用模块时使用句点符调用模块中的变量或者函数,名称不会混乱
缺点:在调用时每次都需要使用句点符。。。。 - from modular_name import parameter 的优缺点
优点:在调用模块时不需要使用句点符,调用方便
缺点:由于不使用句点符调用模块中的功能,可能会名称冲突
- 别名
如果在导入模块时名称太长可以使用 as name来命名别名
import time as ti
or
from register import userinfo as ui, userauth as ua
# 起别名可以使用逗号分隔
- 多模块导入
- 多模块导入的两种方式
1. 多行导入
import time
import os
2. 单行导入
import time, os, sys
# 推荐多行使用,若模块的功能类似推荐在一行导入
- 循环导入
产生这个问题主要是执行文件导入模块时,模块也导入了执行文件作为包,会报错参数无法被找到,解决办法就是在模块执行时先提供执行文件需要的功能
# 执行文件
import register
print('my is run file')
name = '666'
print(register.userinfo)
# 模块文件
import run
print('my is register file')
userinfo = ['wesley', 'other']
def register():
pass
print(run.name)
-------------------------Error------------------------
AttributeError: partially initialized module 'run' has no attribute 'name' (most likely due to a circular import)
------------------------------------------------------
"""
# 解决方案
如果出现这种问题,将模块中的定义变量放在文件的头部,准确来说需要再调用前定义执行文件需要的功能,反之亦是如此
"""
- 判断文件类型
可以使用 __name__来判断当前的文件类型
name : 1. 返回mian着为执行文件本身,若返回为包名则为调用的包
这个功能主要用于模块开发者,如果非测试阶段由其他人调包使用可以通过__name__来判断一些测试指令是否执行,代码如下:
print(my is modular)
def func():
pass
if __name__ == 'main'
print('测试指令')
- all
主要用于如果我们使用from导入模块的时候选择用通配符※匹配所有功能可以使用___all__ ['name', 'age'] 这样的格式限制用户不能调用的功能
-
模块的查找顺序
-
内存
在程序运行后,就算把自定义模块删除也是可以继续使用模块的功能的,因为自定义模块已经被加载到内存中 -
内置
如果自定义和内置模块的名称冲突,会调用自定义模块 -
sys.path 系统环境变量
以执行文件为准,如果前面两个找不到会到系统变量中寻找,一般pycharm会生成python项目的系统变量,而在cmd窗口中只会向环境变量中寻找
# 可以使用sys内置模块将自定义模块的路径加入pycharm未提供的系统变量
import sys
# 查询
print(sys.path)
# 添加
sys.path.append(r'D:\pythonProject03\day17\mymd')
- 模块的相对导入和绝对导入
这里使用的其实就是相对路径和绝对路径的概念
. 代表当前目录 .. 代表上一级目录
# 代码演示
# 如果自定义模块在执行文件的同级目录下,使用相对路径
from . import register
# 如果自定义模块在系统中的某个位置,使用绝对路径
frmo home.python.xxx import register
1. 需要注意,如果模块和模块之间不是同一个位置需要使用绝对路径重新定义路径
- 包的概念
- 包就是很多py文件的集合
- 在python2中包中必须有着__init__.py的入口文件,python3中无此要求