模块
4.1 模块的定义
-
模块的定义:py文件写好了,对程序员直接提供某方面功能的文件
-
包的定义
- 文件夹存储了多个py文件的文件夹
- 如果导入的是一个包,这个包里的模块是默认不能用的
- 导入一个包相当于执行
__init__.py
文件中的内容
-
python2与python3的导包区别
- python2:文件夹中必须要有
__init__.py
文件 - python3:不需要有
__init__.py
文件 - 建议:推荐以后写代码,无论是python2还是python3,都要加上此文件
- python2:文件夹中必须要有
4.2 内置模块
4.2.1 random模块
-
随机数模块
-
方法
-
randint():得到一个随机数
import random # 导入一个模块 v = random.randint(起始,终止) # 得到一个随机数 #示例:生成随机验证码 import random def get_random_code(length=6): data = [] for i in range(length): v = random.randint(65,90) data.append(chr(v)) return ''.join(data) code = get_random_code() print(code)
-
uniform():生成一个随机整小数
import random result = random.uniform(1,5) # 在1~5之间随机产生一个小数,并且位数没有限制 print(result)
-
choice():抽取一个对象
-
应用:验证码、抽奖
import random result = random.chioce([1,2,3,4,5,6,7,8,9]) # 在[1,2,3,4,5,6,7,8,9]中随机抽取一个数据 print(result)
-
-
sample():抽取多个对个对象
-
应用:一个奖项抽取多个人
import random result = random.sample([1,2,3,4,5,6,7,8,9],k=3) # 在[1,2,3,4,5,6,7,8,9]中随机抽取k=3个数据,(k可以设置) print(result)
-
-
shuffle():打乱顺序
- 应用:洗牌、算法
-
4.2.2 hashlib模块
-
摘要算法模块
- 密文验证
- 校验文件的一致性
-
方法
-
md5():将指定的字符串进行加密
示例一:
# 将指定的 “字符串” 进行 加密 import hashlib # 导入一个模块 def get_md5(data): # md5 加密函数 obj = hashlib.md5() obj.update(data.encode('utf-8')) result = obj.hexdigest() return result val = get_md5('123') print(val) # 加盐 import hashlib def get_md5(data): obj = hashlib.md5("sidrsdxff123ad".encode('utf-8')) # 加盐 obj.update(data.encode('utf-8')) result = obj.hexdigest() return result val = get_md5('123') print(val)
示例二:
# 应用:用户注册+用户登录 import hashlib USER_LIST = [] def get_md5(data): # md5 加密函数 obj = hashlib.md5("12:;idrsicxwersdfsaersdfs123ad".encode('utf-8')) # 加盐 obj.update(data.encode('utf-8')) result = obj.hexdigest() return result def register(): # 用户注册函数 print('**************用户注册**************') while True: user = input('请输入用户名:') if user == 'N': return pwd = input('请输入密码:') temp = {'username':user,'password':get_md5(pwd)} USER_LIST.append(temp) def login(): # 用户登录函数 print('**************用户登陆**************') user = input('请输入用户名:') pwd = input('请输入密码:') for item in USER_LIST: if item['username'] == user and item['password'] == get_md5(pwd): return True register() result = login() if result: print('登陆成功') else: print('登陆失败')
-
sha():将指定的字符串进行加密(保密性更好)
示例:
import hashlib md5 = hashlib.sha1('盐'.encode()) md5.update(b'str') print(md5.hexdigest())
-
4.2.3 getpass模块
-
只能在终端上运行
-
方法
-
getpass.getpass():输入密码不显示
示例
import getpass # 导入一个模块 pwd = getpass.getpass('请输入密码:') if pwd == '123': print('输入正确')
-
4.2.4 time模块【常用】
-
时间模块
-
方法
-
time.time():时间戳(从1970年到现在经历的秒数)
-
time.sleep():等待的秒数
-
time.timezone():获取区时
# 计算函数执行时间 import time def wrapper(func): def inner(): start_time = time.time() v = func() end_time = time.time() print(end_time-start_time) return v return inner @wrapper def func1(): time.sleep(2) print(123) func1()
-
4.2.5 datetime模块【常用】
-
时间模块
-
方法
-
datetime.now():获取当前本地时间
-
datetime.utcnow():获取当前英国伦敦时间
import time from datetime import datetime,timezone,timedelta # 获取datetime格式时间 # 当前本地时间 v1 = datetime.now() # 当前东7区时间 tz = timezone(timedelta(hours=7)) v2 = datetime.now(tz) # 当前UTC时间 v3 = datetime.utcnow() print(v3)
-
strftime():将datetime对象转换成str对象
-
strptime():将str对象转换成datetime对象
-
fortimestamp():将时间戳转换成datetime对象
-
timestamp():将datetime对象转换成时间戳
-
时间的加减(转换成时间戳进行加减)
示例
import time from datetime import datetime,timedelta # 1.datetime格式和字符串的相互转换 # 把datetime格式转换成字符串:strftime v1 = datetime.now() val = v1.strftime("%Y-%m-%d %H:%M:%S") # 字符串转成datetime格式:strptime v1 = datetime.strptime('2011-11-11','%Y-%m-%d') # 2.datetime时间的加减 v1 = datetime.strptime('2011-11-11','%Y-%m-%d') v2 = v1 - timedelta(days=140) # 再转换成字符串 date = v2.strftime('%Y-%m-%d') # 3.时间戳和datetime的相互转换 # 时间戳转换成datetime格式:fromtimestamp ctime = time.time() v1 = datetime.fromtimestamp(ctime) # datetime格式转换成时间戳:timestamp v1 = datetime.now() val = v1.timestamp()
-
4.2.6 sys模块
-
python解释器相关数据
-
方法
-
sys.getrefcount():获取一个值得应用计数
-
sys.getrecursionimit():python默认支持的递归数量
-
sys.stdout.write():输入输出
-
补充:\n:换行 ,\t:制表符 ,\r:回到当前行的起始位置
import time for i in range(1,101): msg = "%s%%\r" %i print(msg,end='') time.sleep(0.05)
-
示例:读取文件的进度条
import os # 1. 读取文件大小(字节) file_size = os.stat('20190409_192149.mp4').st_size # 2.一点一点的读取文件 read_size = 0 with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2: while read_size < file_size: chunk = f1.read(1024) # 每次最多去读取1024字节 f2.write(chunk) read_size += len(chunk) val = int(read_size / file_size * 100) print('%s%%\r' %val ,end='')
-
-
sys.args:获取用户执行脚本是,传入的参数【常用】
-
示例:让用户执行脚本传入要删除的文件路径,在内部帮助用户将目录删除
""" 让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删除。 C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py """ import sys # 获取用户执行脚本时,传入的参数。 # C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test # sys.argv = [D:/code/s21day14/7.模块传参.py, D:/test] path = sys.argv[1] # 删除目录 import shutil shutil.rmtree(path)
-
-
sys.eit(0):程序终止,0代表正常终止
-
sys.path:默认python取导入模块时,会按照sys.path中的路径导入【常用】
-
添加目录:sys.path.append(‘目录’)
import sys sys.path.append('D:\\')
-
-
sys.modules:存储了当前程序中所用到的所有模块,反射本文件中的内容【常用】
-
4.2.7 os模块【常用】
-
和操作系统相关的数据
-
方法
-
os.path.exists(path):如果path存在,返回True,如果path不存在,返回False
-
os.stat(‘文件路径’).st_size / os.path.getsize():获取文件大小
-
os.path.abspath():获取一个文件的绝对路径
import os v1 = os.path.abspath(path) print(v1)
-
os.path.dirname():获取路径的上级目录
import os v = r"D:\code\s21day14\20190409_192149.mp4" print(os.path.dirname(v))
-
补充:转义
v1 = r"D:\code\s21day14\n1.mp4" (推荐) v2 = "D:\\code\\s21day14\\n1.mp4"
-
-
os.path.join():路径的拼接
import os path = "D:\code\s21day14" # user/index/inx/fasd/ v = 'n.txt' result = os.path.join(path,v) print(result)
-
os.listdir():查看一个目录下的所有文件【第一层】
import os result = os.listdir(r'D:\code\s21day14') for path in result: print(path)
-
os.walk():查看一个目录所有的文件【所有层】
import os result = os.walk(r'D:\code\s21day14') for a,b,c in result: # a,正在查看的目录 b,此目录下的文件夹 c,此目录下的文件 for item in c: path = os.path.join(a,item) print(path)
-
os.makedir():创建目录,只能产生一层目录(基本不用这个)
-
os.makedirs():创建目录及其子目录(推荐使用)
# 将内容写入指定文件中 import os file_path = r'db\xx\xo\xxxxx.txt' file_folder = os.path.dirname(file_path) if not os.path.exists(file_folder): os.makedirs(file_folder) with open(file_path,mode='w',encoding='utf-8') as f: f.write('asdf')
-
os.rename():重命名
# 将db重命名为sb import os os.rename('db','sb')
-
oa.path.isdir():判断是否是文件夹
-
os.path.isfile():判断是否是文件
-
4.2.8 shutil模块
-
删除、重命名、压缩、解压等
-
方法
-
shutil.rmtree(path):删除目录
# 删除目录 import shutil shutil.rmtree(path)
-
shutil.move():重命名
# 重命名 import shutil shutil.move('test','ttt')
-
shutil.make_archive():压缩文件
# 压缩文件 import shutil shutil.make_archive('zzh','zip','D:\code\s21day16\lizhong')
-
shutil.unpack_archive():解压文件
# 解压文件 import shutil shutil.unpack_archive('zzh.zip',extract_dir=r'D:\code\xxxxxx\xxxx',format='zip')
-
-
综合示例
import os import shutil from datetime import datetime ctime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') # 1.压缩lizhongwei文件夹 zip # 2.放到到 code 目录(默认不存在) # 3.将文件解压到D:\x1目录中。 if not os.path.exists('code'): os.makedirs('code') shutil.make_archive(os.path.join('code',ctime),'zip','D:\code\s21day16\lizhongwei') file_path = os.path.join('code',ctime) + '.zip' shutil.unpack_archive(file_path,r'D:\x1','zip')
4.2.9 json模块
-
json是一个特殊的字符串。长的像列表、字典、字符串、数字等嵌套
-
序列化:八python中的值转化为json格式的字符串
-
反序列化:将json格式的字符串转换成python的数据类型
-
json格式要求:
- 只包含int / str / float / list / dict
- 最外层必须是list / dict
- 在json中,内部str必须是双引号
- 存在字典的key只能是str
- 不能连续load多次
-
方法
-
json.dumps():序列化
-
json只支持dict / list / str / int / float / True / False / None序列化
-
字典或列表如果有中文,序列化时如果想显示中文
import json v = {'k1':'alex','k2':'李杰'} val = json.dumps(v,ensure_ascii = False)
-
-
json.loads():反序列化
import json # 序列化,将python的值转换为json格式的字符串。 v = [12,3,4,{'k1':'v1'},True,'asdf'] v1 = json.dumps(v) print(v1) # 反序列化,将json格式的字符串转换成python的数据类型 v2 = '["alex",123]' print(type(v2)) v3 = json.loads(v2) print(v3,type(v3))
-
json.dump():打开文件,序列化后,写入文件
import json v = {'k1':'alex','k2':'李杰'} f = open('x.txt',mode='w',encoding='utf-8') val = json.dump(v,f) print(val) f.close()
-
json.load():打开文件,读取文件(json格式)内容
import json v = {'k1':'alex','k2':'李杰'} f = open('x.txt',mode='r',encoding='utf-8') data = json.load(f) f.close() print(data,type(data))
-
4.2.10 pickle模块
-
pickle和json的区别
-
json
- 优点:所有语言通用
- 缺点:只能序列化基本数据类型list / dict
-
pickle
- 优点:python中所有的东西都能被他序列化(socket对象),支持连续load多次
- 缺点:序列化的内容只能是python所能识别的
-
-
方法
-
pickle.dumps():序列化
-
序列化后的东西不可读
import pickle # 序列化 v = {1,2,3,4} val = pickle.dumps(v) print(val)
-
-
pickle.loads():反序列化
# 反序列化 import pickle v = {1,2,3,4} data = pickle.loads(val) print(data,type(data))
-
pickle.dump():写入文件(注意:mode=‘wb’)
import pickle # 写入文件 v = {1,2,3,4} f = open('x.txt',mode='wb') val = pickle.dump(v,f) f.close()
-
pickle.load():读取文件(注意:mode=‘wb’)
import pickle # 读取文件 f = open('x.txt',mode='rb') data = pickle.load(f) f.close() print(data)
-
4.2.11 copy模块
-
拷贝模块
-
方法
-
copy.copy():浅拷贝
import copy v1 = [1,2,3] v2 = copy.copy(v1) #浅拷贝
-
copy.deepcopy():深拷贝
import copy v1 = [1,2,3] v3 = copy.deepcopy(v1) #深拷贝
-
4.2.12 importlib模块
-
导入模块包
-
方法
-
importlib.import_moduule():通过字符串的形式导入模块
#示例一: import importlib # 用字符串的形式导入模块。 redis = importlib.import_module('utils.redis') # 用字符串的形式去对象(模块)找到他的成员。 getattr(redis,'func')()
#示例二: import importlib middleware_classes = [ 'utils.redis.Redis', # 'utils.mysql.MySQL', 'utils.mongo.Mongo' ] for path in middleware_classes: module_path,class_name = path.rsplit('.',maxsplit=1) module_object = importlib.import_module(module_path)# from utils import redis cls = getattr(module_object,class_name) obj = cls() obj.connect()
-
4.2.13 collections模块
-
方法
-
OrderedDict():有序字典
from collections import OrderedDict odic = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(odic) for k in odic: print(k,odic[k])
-
defaultdict():默认字典
-
deque():双字典
-
namedtuple:可命名元组
# 创建一个类,这个类没有方法,所有属性的值都不能修改 from collections import namedtuple # 可命名元组 Course = namedtuple('Course',['name','price','teacher']) python = Course('python',19800,'alex') print(python) print(python.name) print(python.price)
-
4.2.14 logging模块
-
日志模块:计入日志的
-
给用户看的:流水类,如银行流水
-
给程序员看的:
- 统计用的
- 用来做故障排除的,debug
- 用来记录错误的,完成代码的优化
-
-
日志处理的本质:Logger \ FileHandler \ Formatter
-
两种配置方式:
-
basicConfig对象
- 优点:使用方便
- 缺点:不能实现编码问题,不能同时向文件和屏幕上输出
-
logger对象
-
优点:能实现编码问题,同同时向文件和屏幕上输出
-
缺点:复杂
-
示例
import logging # 创建一个logger对象 logger = logging.getLogger() # 创建一个文件操作符 fh = logging.FileHandler('log.log') # 创建一个屏幕操作符 sh = logging.StreamHandler() # 给logger对象绑定 文件操作符 logger.addHandler(fh) # 给logger对象绑定 屏幕操作符 logger.addHandler(sh) # 创建一个格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 给文件操作符 设定格式 fh.setFormatter(formatter) # 给屏幕操作符 设定格式 sh.setFormatter(formatter) # 用logger对象来操作 logger.warning('message')
-
-
-
日志异常级别
CRITICAL = 50 # 崩溃 FATAL = CRITICAL ERROR = 40 # 错误 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
-
推荐日志处理方式
import logging file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler,], level=logging.ERROR ) logging.error('你好')
-
推荐处理日志处理方式 + 日志分割
import time import logging from logging import handlers # file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',) file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8') logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler,], level=logging.ERROR ) for i in range(1,100000): time.sleep(1) logging.error(str(i))
-
注意事项:在应用日志时,如果想保留异常的堆栈信息
# 在应用日志时,如果想要保留异常的堆栈信息。 import logging import requests logging.basicConfig( filename='wf.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=logging.ERROR ) try: requests.get('http://www.xxx.com') except Exception as e: msg = str(e) # 调用e.__str__方法 logging.error(msg,exc_info=True)
4.2.15 re模块【正则表达式】(欠着)
4.3 自定义模块
-
自己写的xx.py
def f1(): print('f1') def f2(): print('f2')
-
在yy.py中调用
# 调用自定义模块中的功能 import xx xx.f1() xx.f2()
-
运行
python yy.py
4.4 第三方模块
-
需要下载安装才能导入使用
-
安装方式:
-
pip包管理器
# 把pip.exe 所在的目录添加到环境变量中。 pip install 要安装的模块名称 # pip install xlrd
-
源码安装
# 下载源码包(压缩文件) -> 解压 -> 打开cmd窗口,并进入此目录:cd C:\Python37\Lib\site-packages # 执行:python3 setup.py build # 执行:python3 setup.py install
-
-
安装路径:C:\Python37\Lib\site-packages
4.5 模块的调用
4.5.1 绝对导入
-
模块的基本导入及调用
-
方式一
# 导入模块,加载此模块中所有的值到内存。 import requests # 调用模块中的函数 requests.get()
-
方式二
# 导入pandas中的Series和DataFrame from pandas import Series,DataFrame # 导入pandas中的所有值 from pandas import * # 调用模块中的函数 Series()
-
方式三
# 如果有重名情况,就导入时起一个别名 # 导入pandas.py中的DataFrame,并起一个别名为f from pandas import DataFrame as df # 调用模块中的函数 df()
-
总结
-
导入:import模块,调用:模块.函数()
-
导入:from 模块 import 函数,调用:函数()
-
导入:from 模块 import 函数 as 别名,调用:别名()
-
知识点:
- as:起别名
- *:代表全部
-
-
补充
-
多次导入不再重新加载
import jd # 第一次加载:会加载一遍jd中所有的内容。 import jd # 由已经加载过,就不再加载。 print(456)
-
非要重新加载
import importlib import jd importlib.reload(jd) print(456)
-
-
-
导入文件夹中的py文件及调用
-
导入YYY文件中的XXX.py文件
-
方式一
# 导入模块 import YYY.XXX # 调用模块中的函数 XXX.func()
-
方式二
# 导入模块 from YYY import XXX # 调用模块中的函数 XXX.func()
-
方式三
# 导入模块 from YYY.XXX import func # 调用模块中的函数 func()
-
-
总结
-
模块和执行的py文件在同一目录下且需要模块中的很多功能时,推荐用:
- 导入:import 模块,调用:模块.函数()
-
其他推荐:
- 导入:from 模块 import 模块,调用:模块.函数()
- 导入:from 模块.模块 import 函数,调用:函数()
-
-
4.5.2 相对导入(不推荐)
from . import xxx
from .. import xxx