模块
模块
模块是一系列功能的结合体,本质上是一个个的py文件(相当于模块包着一堆函数)
模块的三种来源
1、python内置的
例如:import sys import os import time import turtle
2、第三方的模块(别人写的)
例如:import requests
3、自定义模块(自己写的)
例如:自己定义的py文件
模块的四种表现形势
1、使用python编写的py文件
2、编译后的共享库
3、包下面带有__ init __.py的一组py文件
包指的是内部包含__ init __.py的文件夹
包可以存放模块,更好的管理模块
4、python解释器下的py文件
为什么要使用模块?
模块可以帮我们更好的管理功能代码,比如函数
可以将项目拆分成一个个功能,分别存放在不同的py文件(模块)中
如何编写模块,并使用模块?
右键创建py文件
在py文件编写python代码
在一个文件中,通过import关键字导入模块
import模块名
例如导入time模块
import time
print('当前时间戳为:',time.time())
# 当前时间戳为: 1573802438.2854111
注意:在使用import 模块时,模块不能加.py后缀
在使用模块阶段,必须要注意,谁是执行文件,谁是被导入文件(被导入模块)
模块在首次导入时就已经固定好了,当文件查找的顺序时先从内存中查找
模块在导入时发生的事情
1、会先执行当前执行文件,并产生执行文件中的名称空间
2、当执行到导入模块的代码时,被导入模块会产生一个模块的名称空间
3、将被导入模块的名称空间加载到内存中
模块的导入方式
import 模块
在执行中直接import导入
from包/模块 import 模块(函数名、变量名、类名)
类似于下面的代码
from functools import reduce
如何解决循环导入问题
1、需要查找的名字放在导入模块的上方
2、在函数内部导入,将模块变成函数名称空间中的名字
下面说一下常见的模块,以及使用方法
time模块:时间模块
time 模块主要包含各种提供日期、时间功能的类和函数。该模块既提供了把日期、时间格式化为字符串的功能,也提供了从字符串恢复日期、时间的功能。
在python中的三种时间表现形式
1、时间戳
自1980-01-01 00:00:00到当前时间,按秒计算,计算了多少秒
2、格式化时间 (From String)
返回的是时间的字符串:2019-01-01这种
3、格式化时间对象
返回的是一个元组,元组中有九个值
- tm_year :年
- tm_mon :月(1-12)
- tm_mday :日(1-31)
- tm_hour :时(0-23)
- tm_min :分(0-59)
- tm_sec :秒(0-59)
- tm_wday :星期几(0-6,0表示周日)
- tm_yday :一年中的第几天(1-366)
- tm_isdst :是否是夏令时(默认为-1)
具体例子如下
import time
# 1、获取当前时间戳(自1970-01-01 00:00:00到当前时间,按秒计算,计算了多少秒。)
print(time.time())
'''
%Y 年
%m 月
%d 日
%H 小时
%M 分钟
%S 秒
'''
# 2、获取格式化时间
# 获取年月日
print(time.strftime('%Y-%m-%d'))
# 获取年月日时分秒
print(time.strftime('%Y-%m-%d %H:%M:%S'))
# %X = %H:%M:%S
print(time.strftime('%Y-%m-%d %X'))
# 获取年月
print(time.strftime('%Y/%m'))
# 3、获取时间对象
time_obj = time.localtime()
print(time_obj.tm_year) # 打印当前年份
print(time_obj.tm_mon) # 打印当前月份
print(time_obj.tm_mday) # 打印当前日期
print(time_obj)
# 获取当前时间的格式化时间
print(time.strftime('%Y-%m-%d %X', time.localtime()))
# 将字符串格式化时间转换为时间对象
res = time.strptime('2019-01-01', '%Y-%m-%d')
print(res)
datetime模块
datetime模块基于 time模块进行了封装,提供了更多实用的函数
具体例子如下:
import datetime
# 获取当前年月日
print(datetime.date.today())
# 获取当前年月日时分秒
print(datetime.datetime.today())
time_obj = datetime.datetime.today()
print(time_obj.year) # 获取当前年份
print(time_obj.month) # 获取当前月份
print(time_obj.day) # 获取当前几号
# 从索引0开始计算周一
# UTC一周0-6(默认)
print(time_obj.weekday())
# ISO正常一周1-7天
print(time_obj.isoweekday())
# (当前时区时间)默认
print(datetime.datetime.now())
# UTC时区(格林威治)
print(datetime.datetime.utcnow())
'''
日期/时间的计算
日期时间 = 日期时间 "+" or "-" 时间对象
时间对象 = 日期时间 "+" or "-" 时间对象
'''
# 日期时间
current_time = datetime.datetime.now()
# 时间对象
time_obj = datetime.timedelta(days=7) # 获取7天时间
# 在现在时间的基础上增加7天
later_time = current_time + time_obj
print(later_time)
# 求later_time相比current_time增加了多长时间
sarts_time = later_time - current_time
print(sarts_time)
random模块:随机模块
例子如下:
# 随机获取1-9的任意整数
res = random.randint(1, 9)
print(res)
# 默认获取0-1之间的任意小数
res2 = random.random()
print(res2)
# 将可迭代中的值进行乱序
# 洗牌
list1 = ['红桃A', '梅花A', '方块A', '黑桃A']
random.shuffle(list1)
print(list1)
# 随机获取可迭代对象中的某一个值
res3 = random.choice(list1)
print(res3)
# # 扩展例题:随机验证码(5位)
'''
需求:
大小写字母、数字组合而成
组合5位数的随机验证码
前置技术:
- chr(97) # 可以将ASCII表中值转换成对应的字符
# print(chr(101))
- random.choice
'''
# 获取任意长度的随机验证码
def get_code(n):
code = ''
# 每次循环只从大小写字母,数字中取出一个字符
for line in range(n):
# 随机获取一个小写的字母(97-122对应的是ASCII表中的小写a-z)
res1 = random.randint(97, 122)
lower_str = chr(res1)
# 随机获取一个大写的字母(65-90对应的是ASCII表中的大写A-Z)
res2 = random.randint(65, 90)
upper_str = chr(res2)
# 随机获取一个数字
number = str(random.randint(0, 9))
code_list = [lower_str, upper_str, number]
random_code = random.choice(code_list)
code += random_code
return code
code = get_code(5)
print(code)
print(len(code))
os模块:与操作系统交互的模块
具体例子如下:
import os
# 输出当前文件的上一级目录
DAY15_PATH = os.path.dirname(__file__)
print(DAY15_PATH)
# 输出项目的根目录
BASE_PATH = os.path.dirname(DAY15_PATH)
TEST_PATH = os.path.join(DAY15_PATH, '老男孩')
print(BASE_PATH)
# 判断文件是否存在
print(os.path.exists(DAY15_PATH))
print(os.path.exists(TEST_PATH))
# 路径拼接:拼接文件“绝对路径”
TEST_PATH = os.path.join(DAY15_PATH, '老男孩')
print(TEST_PATH)
# 判断文件夹是否存在
print(os.path.isdir(TEST_PATH))
print(os.path.isdir(DAY15_PATH))
# 创建文件夹
DIR_PATH = os.path.join(DAY15_PATH, '老男孩')
os.mkdir(DIR_PATH) # 新建老男孩文件夹
# 删除文件夹:只能删除空文件夹
os.rmdir(DIR_PATH)
# 获取某个文件夹中所有文件的名字
teacher_list = os.listdir(r"E:\python\project02\day15\老男孩")
print(teacher_list)
sys模块
提供对解释器使用或维护的一些变量的访问,以及与解释器交互的模块
具体例子如下:
import sys
import os
# 获取当前python解释器的环境变量
print(sys.path)
# 将当前项目添加到环境变量中
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_PATH)
# 获取cmd终端的命令行 python3 py文件 用户名 密码
print(sys.argv) # 返回的是列表
hashlib模块:加密模块
常见的加密方法有md5和sha_265
咱们主要说一下md5,sha_256之作了解
import hashlib
md5_obj = hashlib.md5()
str1 = '1234'
# update中一定要传入bytes类型数据
# 给str1 = 1234 加密
md5_obj.update(str1.encode('utf-8'))
print(str(md5_obj))
# 得到一个加密后的字符串
# 81dc9bdb52d04dc20036dbd8313ed055
res1 = md5_obj.hexdigest()
print(res1)
# 以上操作撞库有可能会破解真实密码
# 防止撞库问题:加盐
# 扩展例子:验证登录功能
def pwd_md5(str1):
md5_obj = hashlib.md5()
# 给str1加密
md5_obj.update(str1.encode('utf-8'))
# 加盐
sa1 = '我怎么这么帅!'
md5_obj.update(sa1.encode('utf-8'))
res = md5_obj.hexdigest()
return res
res = pwd_md5('1234')
user_str1 = f'kang:{res}'
with open('user.txt', 'w', encoding='utf-8')as f:
f.write(user_str1)
# 获取文件中的用户名与密码
with open('user.txt', 'r', encoding='utf-8')as f:
user_str = f.read()
file_user, file_pwd = user_str.split(':')
username = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
# 校验用户名与密码是否一致
if username == file_user and file_pwd == pwd_md5(password):
print("登陆成功")
else:
print("登陆失败")
序列化模块:json和pickle
序列化:将python或其他语言的数据类型转换成字符串
序列化:其他数据类型-->字符串-->文件中
反序列化:文件中-->字符串-->其他数据类型
json模块
什么是json?
json是一个第三方的特殊字符串(数据格式)
为什么要使用json?
为了让不同语言之间数据可以共享
怎么用json?
import json
# 列表类型
list1 = ["123", "321"]
# json.dumps()
# 序列化: python数据类型 ---> json ---> 字符串 ---> json文件中
# ensure_ascii将默认的ascii取消设置为False,可以在控制台看到中文,否则看到的是bytes类型数据
json_str = json.dumps(list1, ensure_ascii=False) # 此时json_str就是字符串类型的了
print(json_str)
# json.loads()
# 反序列化: json文件中 --> 字符串 --->json --> python或其他语言数据类型
python_data = json.loads(json_str) # 此时json_str又变回列表类型了
print(python_data)
# 元组
tuple1 = ("张全蛋", "李小花")
json_str2 = json.dumps(tuple1, ensure_ascii=False) # 此时json_str就是字符串类型的了
print(type(json_str2))
python_data2 = json.loads(json_str2)
print(tuple(python_data2)) # 此时json_str又变回列表类型了
# print(python_data2)
# 字典
dic = {
"name": "tank",
"age": 17
}
json_str3 = json.dumps(dic, ensure_ascii=False)
print(json_str3)
python_data3 = json.loads(json_str3)
print(python_data3)
# 这里要注意集合是不能被序列化成json
# 扩展训练:注册功能
def register():
username = input("请输入账号:").strip()
password = input("请输入密码:").strip()
re_password = input("请再次输入密码:").strip()
if re_password == password:
# [username,password]
# {'name':username, 'pwd':password}
user_dic = {'name': username, 'pwd': password}
json_str4 = json.dumps(user_dic, ensure_ascii=False)
# 开始写入文件
# 注意:保存json数据时,用.json作为文件的后缀名
with open("a.json", "w", encoding="utf-8")as f:
f.write(json_str4)
pickle模块
pickle是一个python自带的序列化模块
优点:
可以支持python中所有的数据类型
可以直接存bytes类型的数据pickle存取速度更快
缺点:致命缺点
只能支持python去使用
collections模块
提供了python自带的八大数据类型以外的数据类型
这里主要说一下具名元组和有序字典
# 具名元组:有名字的元组
from collections import namedtuple
point = namedtuple("坐标", ["x", "y"])
# 传参的个数,要与namedtuple第二个参数的个数一一对应
p = point(1, 2) # 会将 1 ---> x, 2 ---> y
print(p)
# 扑克牌
# 获取扑克牌对象
card = namedtuple("扑克牌", ["color", "number"])
# 由扑克牌对象产生一张扑克牌
red_A = card("♥", "A")
print(red_A)
black_K = card("♠", "K")
print(black_K)
# 有序字典
# python中字典默认无序
dic = dict({'x': 1, 'y': 2, 'z': 3})
print(dic)
for line in dic:
print(line)
from collections import OrderedDict
order_dic = OrderedDict({'x': 1, 'y': 2, 'z': 3})
print(order_dic, "打印有序字典")
print(type(order_dic))
print(order_dic.get("y"))
print(order_dic["y"])
for line in order_dic:
print(line)
openpyxl模块
可以对Excel表格进行操作的模块
需要下载第三方包:pip3 install openpyxl
Excel版本:
2003年以前:excel表名.xls
2003年以后:excel表名.xlsx
下面举例说一下例子:
from openpyxl import Workbook
# 获取Excel文件对象
wb_obj = Workbook()
wb1 = wb_obj.create_sheet("python13期1", 0)
# wb2 = wb_obj.create_chartsheet("python13期2", 2)
# 修改工作表名字
print(wb1.title)
wb1.title = "zhao"
print(wb1.title)
# 为第一张工作表添加值
# wb1['工作表中的表格位置']
wb1["A10"] = 500
wb1["B10"] = 1000
wb1["C10"] = "=SUM(A10:B10)"
# wb2["A10"] = 200
# 生成Excel表
wb_obj.save("python.xlsx")
print(wb_obj)
from openpyxl import load_workbook
wkb_onj = load_workbook("python.xlsx")
wk1 = wkb_onj['python13期1']
print(wk1["A10"].value)
subprocess模块
subprocess可以通过python代码给操作系统终端发送命令并且可以得到返回结果
import subprocess
while True:
# 1.让用户输入终端命令
cmd_str = input('请输入终端命令:').strip()
# Popen(cmd命令, shell=True,
# stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 调用Popen就会将用户的终端命令发送给本地操作系统的终端
# 得到一个对象,对象中包含着正确或错误的结果。
obj = subprocess.Popen(
cmd_str, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
success = obj.stdout.read().decode('gbk')
if success:
print(success, '正确的结果')
error = obj.stderr.read().decode('gbk')
if error:
print(error, '错误的结果')
re模块
说到re模块不得不提一下正则表达式
什么是正则表达式与re模块?
正则表达式:是一门独立的技术,任何语言都可以使用,正则表达式是由一特殊字符组合而来
re模块:在python,若想使用正则表达式,比通过re模块
为什么要使用正则?
比如要获取一堆字符串中的某些字符串,正则表达式可以帮我们过滤,并提取出想要的字符类型
应用场景
爬虫,数据分析,用户名与密码的手机认证
re模块三种比较重要的方法
findall():
可以匹配所有字符,拿到返回的结果,返回的结果是一个列表
str1 = 'sean tank json'
# findall
res1 = re.findall('[a-z]{4}', str1)
print(res1) # ['sean', 'tank', 'json']
search():
可以匹配一个字符,匹配成功后,拿到结果后结束,不往后匹配
# search
res2 = re.search('[a-z]{4}', str1)
print(res2)
print(res2.group()) # sean
match():
从匹配字符的开头匹配,若开头不是想要的内容,则返回None
# match
res3 = re.match('sean', str1)
print(res3)
print(res3.group()) # sean
if res3:
print(res3.group()) # sean
扩展例子
# 检测手机号的合法性
# 需求:11位、开头13/14/15/19
import re
while True:
phone_number = input("请输入手机号码:").strip()
# 需求:11位、开头13/14/15/19
# ^:代表“开头”
# $:代表“结束”
# |:代表“或”
# (13|14):可以获取一个值,判断是否是13或14
# {1}:需要获取一个值 限制数量
# []:分组限制取值范围
# [0-9]:限制只能获取0-9的某一个字符
if re.match("^(13/14/15/19)[0-9]{9}$", phone_number):
print("合法")
else:
print("不合法")
logging模块
用来记录日志的模块,记录用户在软件中的操作
防止导入模块时自动执行测试功能
if __name__ == '__main__':
执行测试模块
logging模块的使用步骤:
logging配置字典
LOGGING_DICT = {...}
# 1.加载log配置字典到logging模块的配置中
logging.config.dictConfig(LOGGING_DIC)
# 2.获取日志对象
logger = logging.getLogger('user')
# 3.通过logger日志对象,调用内部的日志打印
logger.info('需要记录的日志信息')
爬虫(小讲理论)
爬虫四部原理
1、发送请求
2、获取响应数据
3、解析并提取想要的数据
4、保存提取后的数据
爬虫三部曲
1、发送请求
2、解析数据
3、保存提取后的数据
包(理论)
什么是包?
包是一个带有__ inter __.py文件夹,包也可以被导入,并且可以一并导入包下的所有模块
为什么要使用包?
包可以帮我们管理模块,在包中有一个__ init __.py由它来帮我们管理模块
怎么使用包?
-
import 包.模块名
包.模块.名字
-
from 包 import 模块名
-
from 包.模块名 import 模块中的名字
导入包时发生的事情:
1.当包被导入时,会以包中的__ init __ .py 来产生一个名称空间。
2.然后执行__ init __ .py 文件, 会将__ init __ .py 中的所有名字添加到名称空间中。
3.接着会将包下所有的模块的名字加载到__ init __ .py 产生的名称空间中。
4.导入的模块指向的名称空间其实就是__ init __.py产生的名称空间中。