Python基础之模块

时间:2023-01-20 17:03:42

一、关于模块的基础知识

1.模块的本质

  • 内部具有一定功能的py文件

2.模块的分类

  • 自定义模块 程序员自己写的模块文件
  • 内置模块 Python解释器提供的模块
  • 第三模块 别的程序员模块文件(Python背后真正的大佬)

2.两种导入模块的语句及判断执行文件语句

# 用来相对导入
import
# 用来绝对导入
from ··· import···
# 用来判断是否执行文件
if __name__ == '__main__':
    print('哈哈哈 我是执行文件 我可以运行这里的子代码')

二、Python常见内置模块

1.collections模块

1.具名元组:namedtuple
from collections import namedtuple
# 能表示二维坐标 如:点(1,2)
point = namedtuple('点', ['x', 'y'])
card = namedtuple('扑克牌', ['num', 'color'])
c1 = card('A', '黑♠')
c2 = card('A', '红♥')
print(c1, c1.num, c1.color)
print(c2, c2.num, c2.color)

'''
打印结果如下
扑克牌(num='A', color='黑♠') A 黑♠
扑克牌(num='A', color='红♥') A 红♥
'''
2.队列与堆栈
队列:先进先出
堆栈:先进后出
# 队列和堆栈都是一边只能出一边进

2.time时间模块

时间的三种表现形式

  • 时间戳 time.time() 可以得到的是 时间戳 。即 1970年1月1日0时0分0秒到现在时间的偏移量 s
  • 结构化时间 time.struct_time() 主要是给计算机看的 人看不适应
  • 格式化时间 time.strftime()
time.time()  # 时间戳  1674137513.8003848
time.strftime('%Y-%m-%d %H:%M:%S %X') # %H:%M:%S与%X意思一样都可以获取时分秒
time.localtime()  # 以结构化时间的格式打印当地时间
time.sleep(10)  # 让程序原地休息10秒

3.datetime时间模块

datetime.datetime.now()  # 2023-01-19 22:21:13.199755 年月日时分秒 
datetime.datetime.today()  # 2023-01-19 22:22:05.770036 年月日时分秒
datetime.date.today()  # 2023-01-19	年月日
datetime.timedelta(days=3)  # 3 days, 0:00:00 时间差值

4.random随机模块

random.random()  # 随机产生0到1之间的小数
random.randint(1, 6)  # 随机产生1到6之间的整数
random.randrange()  # 随机产生范围
random.choice()  # 随机抽取一个 抽奖的 '一等奖'
random.choices()  # 随机抽取一个 抽奖的 ['一等奖']
random.sample()  # 可以指定一次抽取几个样本
random.shuffle()  # 类似于洗牌 给出一个列表 每次都会随机打乱列表里面数据值的顺序

5.os模块 主要与代码运行所在的操作系统打交道

# 1.创建目录(文件夹)
os.mkdir(r'd1')  # 相对路径 在执行文件所在的路径下创建目录 可以创建单级目录不可以创建多级目录
os.makedirs(r'd2\d22\d222')  # 可以创建多级目录 也可以创建单级目录
# 2.删除目录(文件夹)
os.rmdir(r'd1')  # 只能删空的单级目录 不可以一次性删除多级目录
os.removedirs(r'd2\d22')  # 可以删除多级目录 只能删除空的多级目录
# 3.列举指定路径下内容名称
os.listdir()
os.listdir(r'D:\\')
# 4.删除/重命名文件
os.rename(r'a.txt', r'aaa.txt')
os.remove(r'aaa.txt')
# 5.获取/切换当前工作目录
print(os.getcwd())  # D:\pythonProject03\day19
os.chdir('..')  # 切换到上一级目录
print(os.getcwd())  # D:\pythonProject03
os.mkdir(r'hei')
# 6.动态获取项目根路径(重要)
os.path.abspath(__file__)  # 获取执行文件的绝对路径  
os.path.dirname(__file__) # 获取执行文件所在的目录路径 
# 7.判断路径是否存在(文件、目录)
os.path.exists()   
os.path.isfile()  
os.path.isdir() 
# 8.路径拼接(重要)
os.path.join()
# 9.获取文件大小(字节)
print(os.path.getsize(r'a.txt'))

6.sys模块 主要与python解释器打交道

sys.path  # 获取执行文件的sys.path路径
sys.getrecursionlimit()  # 获取Python解释器默认最大递归深度
sys.setrecursionlimit(2000)  #修改Python默认最大递归深度
sys.version  # 获取当前解释器的版本信息
sys.platform  # 可以获取平台信息  win32 

7.json序列化模块 序列化可以打破语言限制实现不同编程语言之间数据交互

# json格式数据的形式
字符串类型并且引号都是双引号
针对数据
json.dumps()  # 序列化 字典类型转换为json格式
json.loads()  # 反序列化 json格式转换为字典类型
针对文件
json.dump()
json.load()
d = {'name': 'jason老师', 'pwd': 123}
# json模块针对中文不会自动转码 
res = json.dumps(d, ensure_ascii=False)
print(res)

8.hashlib加密模块

# 何为加密
将明文数据处理成密文数据 让人无法看懂
加密算法不变 内容如果相同 那么结果肯定相同

# 为什么加密
保证数据的安全

# 如何判断数据是否是加密的
一串没有规律的字符串(数字、字母、符号)
加密之后的结果是无法反解密的

# 密文的长短有何讲究
密文越长表示使用的加密算法(数据的处理过程)越复杂

# 常见的加密算法有哪些
md5、base64、hmac、sha系列

# 动态加盐
干扰项是随机变化的 eg:当前时间、用户名部分...
'''加密基本操作'''
import hashlib
# 1.选择加密算法
md5 = hashlib.md5()
# 2.传入明文数据
md5.update(b'hello')
# 3.获取加密密文
res = md5.hexdigest()
print(res)  # 5d41402abc4b2a76b9719d911017c592
'''加密加盐处理操作'''
# 1.选择加密算法
md5 = hashlib.md5()
# 2.传入明文数据
md5.update('公司设置的干扰项'.encode('utf8'))
md5.update(b'hello python')  # 一次性传可以
# 3.获取加密密文
res = md5.hexdigest()
print(res)  # e53024684c9be1dd3f6114ecc8bbdddc

9.subprocess模块 模拟操作系统终端 执行命令并获取结果

import subprocess

res = subprocess.Popen(
    'asdas',  # 操作系统要执行的命令
    shell=True,  # 固定配置
    stdin=subprocess.PIPE,  # 输入命令
    stdout=subprocess.PIPE,  # 输出结果
)
print('正确结果', res.stdout.read().decode('gbk'))  # 获取操作系统执行命令之后的正确结果
print('错误结果', res.stderr)  # 获取操作系统执行命令之后的错误结

10.logging日志模块

# 日志的组成
产生日志
过滤日志
输出日志
日志格式

# 如何理解日志
日志就是记录行为举止的操作

# 日志的级别
有五种级别 代码不需要掌握 会CV并稍作修改即可
import logging
# logging.debug('debug message')
# logging.info('info message')
# logging.warning('warning message')
# logging.error('error message')
# logging.critical('critical message')
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf8',)
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 logging

# 1.日志的产生(准备原材料)        logger对象
logger = logging.getLogger('购物车记录')
# 2.日志的过滤(剔除不良品)        filter对象>>>:可以忽略 不用使用
# 3.日志的产出(成品)             handler对象
hd1 = logging.FileHandler('a1.log', encoding='utf-8')  # 输出到文件中
hd2 = logging.FileHandler('a2.log', encoding='utf-8')  # 输出到文件中
hd3 = logging.StreamHandler()  # 输出到终端
# 4.日志的格式(包装)             format对象
fm1 = logging.Formatter(
        fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
)
fm2 = logging.Formatter(
        fmt='%(asctime)s - %(name)s:  %(message)s',
        datefmt='%Y-%m-%d',
)
# 5.给logger对象绑定handler对象
logger.addHandler(hd1)
logger.addHandler(hd2)
logger.addHandler(hd3)
# 6.给handler绑定formmate对象
hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)
# 7.设置日志等级
logger.setLevel(10)  # debug
# 8.记录日志
logger.debug('写了半天 好累啊 好热啊')
import logging
import logging.config
# 定义日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'  # 其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
# 自定义文件路径
logfile_path = 'a3.log'
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},  # 过滤日志
    'handlers': {
        # 打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        # 打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        # logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
        # '购物车记录': {
        #     'handlers': ['default','console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
        #     'level': 'WARNING',
        #     'propagate': True,  # 向上(更高level的logger)传递
        # },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
    },
}
logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
# logger1 = logging.getLogger('购物车记录')
# logger1.warning('尊敬的VIP客户 晚上好 您又来啦')
# logger1 = logging.getLogger('注册记录')
# logger1.debug('jason注册成功')
logger1 = logging.getLogger('红浪漫顾客消费记录')
logger1.debug('慢男 猛男 骚男')

11.re模块 关于正则相关的模块

import re
re.findall(正则表达式,待匹配的内容)  
re.finditer(正则表达式,待匹配的内容)
re.search(正则表达式,待匹配的内容)
re.match(正则表达式,待匹配的内容)
obj = re.compile(正则表达式)

re.split()  # 切割
re.sub()  # 替换
re.subn()  # 替换

分组优先展示
findall()  # 默认分组优先
findall((?:\d))  # 取消分组优先

分组起别名
(?P<user_id>\d)
res = re.search()
res.group(0)
res.group('user_id')

关于正则表达式 是一门独立的语言

中括号括起来 里面填写一些内容
[0123456789]
[0-9]
[a-z]
[A-Z]
[0-9A-Za-z]
"""
字符组默认情况下筛选数据是挨个挨个匹配 字符组内所有的内容默认都是或关系
"""
.			匹配除换行符意外的任意字符
\w			匹配数字、字母、下划线
\W			匹配除数字、字母、下划线
\d			匹配数字
^			匹配字符串的开头
$			匹配字符串的结尾
()			正则表达式分组
[^]			中括号内取反操作查找其他
a|b			匹配a或者b
"""特殊符号默认情况下筛选数据也是挨个挨个匹配"""
*			零次或多次
+			一次或多次
?			零次或一次
{n}			 n次
{n,}		 n次或多次
{n,m}		 n到m次
"""量词默认情况下都是贪婪匹配>>>:尽可能多的匹"""
量词后面如果跟了问号则会变为非贪婪匹配
.*
.*?
"""
使用贪婪匹配或者非贪婪匹配 建议在前后加上明确的结束标志
"""

12.requests网络爬虫模块 能够模拟浏览器发送网络请求

'''爬取博客园文件'''
import re

import requests

blog_a_list = []
for i in range(1, 3):
    url_text = requests.get(f"https://www.cnblogs.com/almira998/default.html?page={i}").text
    # https: // www.cnblogs.com / Leethon - lizhilog /
    # https://www.cnblogs.com/almira998/
    # print(url_text)
    blog_url = re.findall('<a class="postTitle2 vertical-middle" href="(.*?)">', url_text)
    for url in blog_url:
        res = requests.get(url).text
        blog_title = re.findall('<title>(.*?) - 阿丽米热 - 博客园</title>', res)
        # with open(f'{blog_title}.txt', 'w',encoding='utf8')as f:
        #     for line in res:
        #         f.write(line)
        blog_a_list.append(f'- [{blog_title[0]}]({url})')

blog_a_list.reverse()
for blog_a in blog_a_list:
    print(blog_a)

'''爬取链家二手房数据'''
import requests
import re

res = requests.get('https://sh.lianjia.com/ershoufang/pudong/')
# print(res.text)
data = res.text

home_title_list = re.findall(
    '<a class="" href=".*?" target="_blank" data-log_index=".*?"  data-el="ershoufang" data-housecode=".*?" data-is_focus="" data-sl="">(.*?)</a>',
    data)
# print(home_title_list)
home_name_list = re.findall('<a href=".*?" target="_blank" data-log_index=".*?" data-el="region">(.*?) </a>', data)
# print(home_name_list)
home_street_list = re.findall(
    '<div class="positionInfo"><span class="positionIcon"></span><a href=".*?" target="_blank" data-log_index=".*?" data-el="region">.*? </a>   -  <a href=".*?" target="_blank">(.*?)</a> </div>',
    data)
# print(home_street_list)
home_info_list = re.findall('<div class="houseInfo"><span class="houseIcon"></span>(.*?)</div>', data)
# print(home_info_list)
home_watch_list = re.findall('<div class="followInfo"><span class="starIcon"></span>(.*?)</div>', data)
# print(home_watch_list)
home_total_price_list = re.findall(
    '<div class="totalPrice totalPrice2"><i> </i><span class="">(.*?)</span><i>万</i></div>', data)
# print(home_total_price_list)
home_unit_price_list = re.findall(
    '<div class="unitPrice" data-h><span>(.*?)</span></div>', data)
# print(home_unit_price_list)
home_data = zip(home_title_list, home_name_list, home_street_list, home_info_list, home_watch_list,
                home_total_price_list, home_unit_price_list)
with open(r'home_data.txt','w',encoding='utf8') as f:
    for data in home_data:
        print(
            """
            房屋标题:%s
            小区名称:%s
            街道名称:%s
            详细信息:%s
            关注程度:%s
            房屋总价:%s
            房屋单价:%s
            """%data
        )
        f.write("""
                房屋标题:%s
                小区名称:%s
                街道名称:%s
                详细信息:%s
                关注程度:%s
                房屋总价:%s
                房屋单价:%s\n
                """%data)

三、Python第三方模块

第三方模块:别人写的模块 一般情况下功能都特别强大
    
我们如果想使用第三方模块 第一次必须先下载后面才可以反复使用(等同于内置模块)

下载第三方模块的方式
	1.pip工具
    	注意每个解释器都有pip工具 如果我们的电脑上有多个版本的解释器那么我们在使用pip的时候一定要注意到底用的是哪一个 否则极其任意出现使用的是A版本解释器然后用B版本的pip下载模块
       为了避免pip冲突 我们在使用的时候可以添加对应的版本号
    	   python27			 pip2.7
     	  python36			pip3.6
         python38			pip3.8
  		下载第三方模块的句式
        	pip install 模块名
       下载第三方模块临时切换仓库
    		 pip install 模块名 -i 仓库地址
       下载第三方模块指定版本(不指定默认是最新版)
    		 pip install 模块名==版本号 -i 仓库地址
 	2.pycharm提供快捷方式
    	群内截图
      	
"""
下载第三方模块可能会出现的问题
	1.报错并有警告信息
		WARNING: You are using pip version 20.2.1;
		原因在于pip版本过低 只需要拷贝后面的命令执行更新操作即可
		d:\python38\python.exe -m pip install --upgrade pip
		更新完成后再次执行下载第三方模块的命令即可
	2.报错并含有Timeout关键字
		说明当前计算机网络不稳定 只需要换网或者重新执行几次即可
	3.报错并没有关键字
		面向百度搜索
			pip下载XXX报错:拷贝错误信息
		通常都是需要用户提前准备好一些环境才可以顺利下载
	4.下载速度很慢
		pip默认下载的仓库地址是国外的 python.org
		我们可以切换下载的地址
		pip install 模块名 -i 仓库地址
		pip的仓库地址有很多 百度查询即可
		清华大学 :https://pypi.tuna.tsinghua.edu.cn/simple/
		阿里云:http://mirrors.aliyun.com/pypi/simple/
		中国科学技术大学 :http://pypi.mirrors.ustc.edu.cn/simple/
		华中科技大学:http://pypi.hustunique.com/
		豆瓣源:http://pypi.douban.com/simple/
		腾讯源:http://mirrors.cloud.tencent.com/pypi/simple
		华为镜像源:https://repo.huaweicloud.com/repository/pypi/simple/
"""

四、关于软件开发目录

文件以及目录的名字可以变换 不是已经固定死了的 但是思想是不变的>>>:分类管理
目录规范主要规定开发程序的过程中针对不同的文件功能需要做不同的分类、以下举例

  1. bin文件夹 start.py 启动文件
  2. conf文件夹 settings.py 配置文件
  3. core文件夹 src.py 核心文件
  4. interface文件夹 login.py 接口文件
  5. db文件夹 db_handler.py 数据库的
  6. log文件夹 log.log 日志文件
  7. lib文件夹 common.py 公共功能
  8. readme文件 txt文件 相关说明
  9. requirements.txt 不能写错 模块版本