模块

模块

模块是一系列功能的结合体,本质上是一个个的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、格式化时间对象

返回的是一个元组,元组中有九个值

  1. tm_year :年
  2. tm_mon :月(1-12)
  3. tm_mday :日(1-31)
  4. tm_hour :时(0-23)
  5. tm_min :分(0-59)
  6. tm_sec :秒(0-59)
  7. tm_wday :星期几(0-6,0表示周日)
  8. tm_yday :一年中的第几天(1-366)
  9. 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产生的名称空间中。

posted @ 2019-11-15 16:11  小小小小小小小小小白  阅读(154)  评论(1编辑  收藏  举报