day15 内置模块和开发规范

目标:掌握常见的内置模块的使用及了解软件开发的规范。

今日概要:

  • 内置模块

    • json
    • time
    • datetime
    • re
  • 开发规范
    • 主文件
    • 配置文件
    • 数据
    • 附件
    • 业务代码

1. 内置模块

1.1 json

json模块:是 python 内部的一个模块,可以将 python 的数据格式转换为 json 格式的数据,也可以将 json 格式的数据转换为 python 的数据格式。

json 格式:是一个数据格式(本质上就是个字符串,常用于网络数据传输)

# Python中的数据类型的格式
data = [{"id": 1, "name": "轩小陌", "age": 18},{"id": 2, "name": "alex", "age": 18},('xuanxiaomo',123),
]# JSON格式
value = '[{"id": 1, "name": "轩小陌", "age": 18}, {"id": 2, "name": "alex", "age": 18},["xuanxiaomo",123]]'

1.1.1 核心功能

json格式用于跨语言数据传输,例如:A系统用Python开发,有列表类型和字典类型等。B系统用Java开发,有数组、map等的类型。语言不同,基础数据类型格式都不同。

为了方便数据传输,大家约定一个格式:json 格式,每种语言都可以将自己数据类型转换为 json 格式,也可以将 json 格式的数据转换为各自语言的数据类型。

Python 数据类型与 json 格式的相互转换:

  • 数据类型 -> json ,一般称为:序列化

    import jsondata = [{"id": 1, "name": "轩小陌", "age": 18},{"id": 2, "name": "alex", "age": 18},
    ]res = json.dumps(data)
    print(res)
    >>输出结果:
    [{"id": 1, "name": "\u8f69\u5c0f\u964c", "age": 18}, {"id": 2, "name": "alex", "age": 18}]res = json.dumps(data, ensure_ascii=False)
    print(res)
    >>输出结果:
    [{"id": 1, "name": "轩小陌", "age": 18}, {"id": 2, "name": "alex", "age": 18}]
    
  • json格式 -> 数据类型,一般称为:反序列化

    import jsondata_string = '[{"id": 1, "name": "轩小陌", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'data_list = json.loads(data_string)
    print(data_list)
    >>输出结果:
    [{'id': 1, 'name': '轩小陌', 'age': 18}, {'id': 2, 'name': 'alex', 'age': 18}]
    

练习题

  1. 写网站,给用户返回 json 格式数据

    • 安装 flask 模块,协助我们快速写网站:

      pip3 install flask
      
    • 使用flask写网站

      import json
      from flask import Flaskapp = Flask(__name__)def index():return "首页"def users():data = [{"id": 1, "name": "武沛齐", "age": 18},{"id": 2, "name": "alex", "age": 18},]return json.dumps(data)app.add_url_rule('/index/', view_func=index, endpoint='index')
      app.add_url_rule('/users/', view_func=users, endpoint='users')if __name__ == '__main__':app.run()
      
  2. 发送网络请求,获取 json 格式数据并处理。

    import json
    import requestsurl = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=5&page_start=20"res = requests.get(url=url,headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"}
    )# 获取json格式的数据:
    print(res.text)# 将json格式转换为python数据类型:
    data_dict = json.loads(res.text)
    print(data_dict)
    

1.1.2 类型要求

python的数据类型转换为 json 格式,对数据类型是有要求的,默认只支持:

    +-------------------+---------------+| Python数据类型     | JSON          |+===================+===============+| dict              | object        |+-------------------+---------------+| list, tuple       | array         |+-------------------+---------------+| str               | string        |+-------------------+---------------+| int, float        | number        |+-------------------+---------------+| True              | true          |+-------------------+---------------+| False             | false         |+-------------------+---------------+| None              | null          |+-------------------+---------------+
data = [{"id": 1, "name": "轩小陌", "age": 18},{"id": 2, "name": "alex", "age": 18},
]

其他类型如果想要支持,需要自定义JSONEncoder 才能实现【目前只需要了解大概意思即可,以后项目开发中用到了还会详细讲解。】,例如:

import json
from decimal import Decimal
from datetime import datetimedata = [{"id": 1, "name": "轩小陌", "age": 18, 'size': Decimal("18.99"), 'ctime': datetime.now()},{"id": 2, "name": "alex", "age": 18, 'size': Decimal("9.99"), 'ctime': datetime.now()},
]# 定义一个MyJSONEncoder类,继承JSONEncoder类:
class MyJSONEncoder(json.JSONEncoder):def default(self, o):# 新增条件判断:当数据类型为Decimal和datetime时,分别进行特殊处理:if type(o) == Decimal:return str(o)elif type(o) == datetime:return o.strftime("%Y-%M-%d")# 对于其他常规数据类型,仍然按原类中的处理方式:return super().default(o)res = json.dumps(data, cls=MyJSONEncoder)
print(res)

1.1.3 其他功能

json模块中常用的是:

  • json.dump,将数据序列化并写入文件(不常用)

    import jsondata = [{"id": 1, "name": "轩小陌", "age": 18},{"id": 2, "name": "alex", "age": 18},
    ]file_object = open('xxx.json', mode='w', encoding='utf-8')
    json.dump(data, file_object)
    file_object.close()
    
  • json.load,读取文件中的数据并反序列化为 python 的数据类型(不常用)

    import jsonfile_object = open('xxx.json', mode='r', encoding='utf-8')data = json.load(file_object)
    print(data)
    file_object.close()
    

1.2 时间处理

  • UTC/GMT:世界时间

  • 本地时间:本地时区的时间。

Python中关于时间处理的模块有两个,分别是 time 和 datetime 。

1.2.1 time

import time
1.2.1.1 time.time()

获取当前时间戳(自1970-1-1 00:00起至今经历的时间长度,单位s)

v1 = time.time()
print(v1)
>>输出结果:
1648884242.374617
1.2.1.2 time.timezone

获取当地时区

v2 = time.timezone
print(v2/60/60)
>>输出结果:
-8.0        # 北京位于东八区
1.2.1.3 time.sleep()

暂停n秒,再执行后续的代码。

time.sleep(5)

1.2.2 datetime

from datetime import datetime, timezone, timedelta

在平时开发过程中的时间一般是以为如下三种格式存在:datetime、字符串和时间戳。

1.2.2.1 datetime.now()

获取当前本地时间

v1 = datetime.now()
print(v1)
>>输出结果:2022-04-02 15:28:06.315501
1.2.2.2 datetime.utcnow()

获取当前UTC时间

v2 = datetime.utcnow()
print(v2)
>>输出结果:2022-04-02 07:28:06.315501

1.2.2.3 timezone(timedelta(hours=**))

获取其他时区时间

tz = timezone(timedelta(hours=7))  # hours=7代表东七区
v3 = datetime.now(tz)
print(v3)
>>输出结果:2022-04-02 14:28:06.315501+07:00

1.2.2.4 datetime类型 + timedelta类型

时间的加法

v1 = datetime.now()
v2 = v1 + timedelta(days=140, minutes=5)    # datetime类型 + timedelta类型
print(v1)
print(v2)
>>输出结果:
2022-04-02 15:33:54.839277
2022-08-20 15:38:54.839277

1.2.2.5 datetime类型 - datetime类型

时间的相减,计算间隔时间

v1 = datetime.now()
v2 = datetime.utcnow()
data = v1 - v2
print(v1)
print(v2)
print(data)
>>输出结果:
2022-04-02 15:37:15.568317
2022-04-02 07:37:15.568317
8:00:00
1.2.2.6 datetime.strptime()

字符串格式时间 --> datetime格式时间

text = "2021-11-11"
v1 = datetime.strptime(text,'%Y-%m-%d')  # %Y:年 %m:月份 %d:天
print(v1)
>>输出结果:
2021-11-11 00:00:00
1.2.2.7 datetime.strftime()

datetime格式时间 --> 字符串格式时间

v1 = datetime.now()
val = v1.strftime("%Y-%m-%d %H:%M:%S")
print(val)
print(type(val)
>>输出结果:
2022-04-02 15:41:47
<class 'str'>
1.2.2.8 datetime.fromtimestamp()

时间戳格式时间 --> datetime格式时间

ctime = time.time()
v1 = datetime.fromtimestamp(ctime)
print(v1)
>>输出结果:
2022-04-02 15:42:41.829192
1.2.2.9 datetime.timestamp()

datetime格式时间 --> 时间戳格式时间

v1 = datetime.now()
val = v1.timestamp()
print(val)
>>输出结果:
1648885385.048261

练习题

  1. 日志记录,将用户输入的信息写入到文件,文件名格式为年-月-日-时-分.txt

    # 以自动获取的时间作为文件名,可以实现每隔一段时间创建一个新文件,便于减少单个文件的数据量:
    from datetime import datetimewhile True:text = input("请输入内容:")if text.upper() == "Q":breakcurrent_datetime = datetime.now().strftime("%Y-%m-%d-%H-%M")file_name = "{}.txt".format(current_datetime)with open(file_name, mode='a', encoding='utf-8') as file_object:file_object.write(text)file_object.flush()
    
  2. 用户注册,将用户信息写入Excel,其中包含:用户名、密码、注册时间 三列。

    import os
    import hashlib
    from datetime import datetimefrom openpyxl import load_workbook
    from openpyxl import workbook# 定义全局变量:当前项目目录BASE_DIR,要写入的Excel文件名:
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    FILE_NAME = "db.xlsx"# 定义md5加密函数,对用户输入的密码进行加密:
    def md5(origin):hash_object = hashlib.md5("sdfsdfsdfsd23sd".encode('utf-8'))hash_object.update(origin.encode('utf-8'))return hash_object.hexdigest()# 定于写入函数,将用户输入的用户名和密码写入文件中:
    def register(username, password):db_file_path = os.path.join(BASE_DIR, FILE_NAME)# 判断文件路径是否存在,如果存在,就在Excel的最后一行往下写,如果不存在就从第一行开始写:if os.path.exists(db_file_path):wb = load_workbook(db_file_path)sheet = wb.worksheets[0]next_row_position = sheet.max_row + 1else:wb = workbook.Workbook()sheet = wb.worksheets[0]next_row_position = 1user = sheet.cell(next_row_position, 1)user.value = usernamepwd = sheet.cell(next_row_position, 2)pwd.value = md5(password)# 获取当前时间并转换为字符串,写入Excel中:ctime = sheet.cell(next_row_position, 3)ctime.value = datetime.now().strftime("%Y-%m-%d %H:%M:%S")wb.save(db_file_path)# 定义执行的主函数:
    def run():while True:username = input("请输入用户名:")if username.upper() == "Q":breakpassword = input("请输入密码:")register(username, password)# 运行脚本:
    if __name__ == '__main__':run()
    

1.3 正则表达式相关

如果有一大堆文本信息,需要提取其中的指定数据时,可以使用正则来实现。例如:提取文本中的邮箱和手机号

import retext = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"phone_list = re.findall("1[3|5|8|9]\d{9}", text)
print(phone_list)
>>输出结果:
['15131255789']

1.3.1 正则表达式

import re
1. 字符相关
“固定字符串” 匹配文本中的固定字符串
text = "你好xuanxiaomob,阿斯顿发xuanxiaomasc 阿士大夫能接受的xuanxiaomoff"
data_list = re.findall("xuanxiaomo", text)   #从文本中找到固定字符串"xuanxiaomo"
print(data_list)
>>输出结果:
['xuanxiaomo', 'xuanxiaomo']
[abc] 匹配 a 或 b 或 c 字符。
text = "你好xuanxiaomob,阿斯顿发xuanxiaomasc 阿士大夫能接受的xuanxiaomoff"
data_list = re.findall("[abc]", text)    # [abc]表示从文本中找到字母a或b或c
print(data_list)
>>输出结果:
['a', 'a', 'b', 'a', 'a', 'a', 'c', 'a', 'a']
text = "你好xuanxiaomob,阿斯顿发xuanxiaomasc 阿士大夫能接受的xuanxiaomoff"
data_list = re.findall("i[abc]", text)       # i[abc]表示字母i是固定的
print(data_list)
>>输出结果:
['ia', 'ia', 'ia']
[^abc] 匹配除了 a b c 以外的其他字符。
text = "你wffbbupceiqiff"
data_list = re.findall("[^abc]", text)
print(data_list)
>>输出结果:
['你', 'w', 'f', 'f', 'u', 'p', 'e', 'i', 'q', 'i', 'f', 'f']
[a-z] ,[0-9]匹配 a ~ z , 0 ~ 9 的任意字符。
text = "alexrootrootadmin"
data_list = re.findall("t[a-z]", text)
print(data_list)
>>输出结果:
['tr', 'ta']
. 代指除换行符以外的任意字符。
text = "alexraotrootadmin"
data_list = re.findall("r.o", text)
print(data_list)
>>输出结果:
['rao', 'roo']
.+ 代指除换行符以外的所有字符(贪婪匹配)
text = "alexraotrootadmin"
data_list = re.findall("r.+o", text) # 贪婪匹配
print(data_list)
>>输出结果:
['raotroo']
.+? 代指除换行符以外的所有字符(非贪婪匹配)
text = "alexraotrootadmin"
data_list = re.findall("r.+?o", text) # 非贪婪匹配
print(data_list)
>>输出结果:
['rao']
\w 代指字母或数字或下划线(汉字)。
text = "北京轩小alex陌北  京轩小alex陌"
data_list = re.findall("轩\w+x", text)
print(data_list)
>>输出结果:
['轩小alex', '轩小alex']
\d 代指数字
text = "root-ad32min-add3-admd1in"
data_list = re.findall("d\d", text)
print(data_list)
>>输出结果:
['d3', 'd3', 'd1']
text = "root-ad32min-add3-admd1in"
data_list = re.findall("d\d+", text)
print(data_list)
>>输出结果:
['d32', 'd3', 'd1']
\s 代指任意的空白符,包括空格、制表符等。
text = "root admin add admin"
data_list = re.findall("a\w+\s\w+", text)
print(data_list)
>>输出结果:
['admin add']
2. 数量相关
* 重复0次或更多次
text = "他是大B个,确实是个大2B,也是个大2222B。"
data_list = re.findall("大2*B", text)
print(data_list)
>>输出结果:
['大B', '大2B', '大2222B']
+ 重复1次或更多次
text = "他是大B个,确实是个大2B,大3B,大66666B。"
data_list = re.findall("大\d+B", text)
print(data_list)
>>输出结果:
['大2B', '大3B', '大66666B']
? 重复0次或1次
text = "他是大B个,确实是个大2B,大3B,大66666B。"
data_list = re.findall("大\d?B", text)
print(data_list)
>>输出结果:
['大B', '大2B', '大3B']
{n} 重复n次
text = "楼主太牛逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("151312\d{5}", text)
print(data_list)
>>输出结果:
['15131255789']
{n,} 重复n次或更多次
text = "楼主太牛逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("\d{9,}", text)
print(data_list)
>>输出结果:
['4426625781', '15131255789']
{n,m} 重复n到m次
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("\d{10,15}", text)
print(data_list)
>>输出结果:
['15131255789']
3. 括号(分组)
提取数据区域
text = "楼主太牛逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("15131(2\d{5})", text)    # 匹配成功后,只提取括号内的数据
print(data_list)
>>输出结果:
['255789']
text = "楼主太牛逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来15131266666呀"
data_list = re.findall("15(13)1(2\d{5})", text)  # 匹配成功后,只提取括号内的数据
print(data_list)
>>输出结果:
[ ('13', '255789') ]
text = "楼主太牛逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("(15131(2\d{5}))", text)  # 匹配成功后,同时提取整段数据和括号内的部分端数据
print(data_list)
>>输出结果:
[ ('15131255789', '255789') ]
获取指定区域 + 或条件
text = "楼主15131root太牛15131alex逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("15131(2\d{5}|r\w+太)", text)
print(data_list)
>>输出结果:
['root太', '255789']
text = "楼主15131root太牛15131alex逼了,在线想要 4426625781@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("(15131(2\d{5}|r\w+太))", text)
print(data_list)
>>输出结果:
[('15131root太', 'root太'), ('15131255789', '255789')]

练习题

  1. 利用正则匹配QQ号码

    [1-9]\d{4,}       # 开头不为0,至少为5位数以上的QQ号
    
  2. 身份证号码

    import retext = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("\d{17}[\dX]", text)  # 前17位为数字,最后一位为数字或X
    print(data_list)
    >>输出结果:
    ['130429191912015219', '13042919591219521X']
    
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("\d{17}(\d|X)", text) #前17位为数字,最后一位为数字或X,只提取最后一位
    print(data_list)
    >>输出结果:
    ['9', 'X']
    
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("(\d{17}(\d|X))", text)   #前17位为数字,最后一位为数字或X,提取18位号码和最后一位
    print(data_list)
    >>输出结果:
    [('130429191912015219', '9'), ('13042919591219521X', 'X')]
    
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)", text) # 前17位为数字,最后一位为数字或X,从前往后顺序提取6位,4位,2位,2位,3位,1位
    print(data_list)
    >>输出结果:
    [('130429', '1919', '12', '01', '521', '9'), ('130429', '1959', '12', '19', '521', 'X')]
    
  3. 手机号

    import retext = "我的手机号是15133377892,你的手机号是1171123啊?"
    data_list = re.findall("1[3-9]\d{9}", text)  # 第1位是数字1,第二位是数字3~9,后面9位是任意数字
    print(data_list)
    >>输出结果:
    ['15133377892']
    
  4. 邮箱地址

    import retext = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("\w+@\w+\.\w+",text) # 数字、字母或下划线、汉字开头,中间有个@,接着有个.,最后位是1个数字、字母或下划线、汉字
    print(email_list)
    >>输出结果:
    ['442662578@qq.com和xxxxx']
    
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+", text, re.ASCII)
    # [a-zA-Z0-9_-]表示大小写字母或数字或下划线或'-'  '.'在正则中表示除换行符以外的任意字符,这里加上'\.'进行了转义,单纯地表示'.'
    print(email_list)
    >>输出结果:
    ['442662578@qq.com', 'xxxxx@live.com']
    
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("\w+@\w+\.\w+", text, re.ASCII)   # re.ASCII表示按ascii码进行匹配,默认去除了汉字
    print(email_list)
    >>输出结果:
    ['442662578@qq.com', 'xxxxx@live.com']
    
    text = "楼主太牛44266-2578@qq.com逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)", text, re.ASCII)
    # *表示出现0次或n次,所以([-+.]\w+)*表示如果出现'-'或'+'或'.',它后面一定要接个字母、数字或下划线
    print(email_list)
    >>输出结果:
    [('44266-2578@qq.com', '-2578', '', ''), ('xxxxx@live.com', '', '', '')]
    
  5. 补充代码,实现获取页面上的所有评论(已实现),并提取里面的邮箱。

    # 先安装两个模块
    pip3 install requests
    pip3 install beautifulsoup4
    
    import re
    import requests
    from bs4 import BeautifulSoupres = requests.get(url="https://www.douban.com/group/topic/79870081/",headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',}
    )
    bs_object = BeautifulSoup(res.text, "html.parser")
    comment_object_list = bs_object.find_all("p", attrs={"class": "reply-content"})
    for comment_object in comment_object_list:text = comment_object.textprint(text)# 请继续补充代码,提取text中的邮箱地址email_list = re.findall("\w+@\w+\.\w+", text, re.ASCII)if email_list:print(email_list)
    
4. ^ 起始和$ 结束

上述示例中都是去一段文本中提取数据,只要文本中存在即可。

但如果要求用户输入的内容必须是指定的内容开头和结尾,就需要用到如下两个字符。

  • ^ 开始
  • $ 结束
text = "啊442662578@qq.com我靠"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list)
>>输出结果:
[]
text = "442662578@qq.com"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list)
>>输出结果:
['442662578@qq.com']

这两种字符一般用于对用户输入数据格式的校验比较多,例如:

import retext = input("请输入邮箱:")
email = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
if not email:print("邮箱格式错误")
else:print(email)
5. 特殊字符

由于正则表达式中 * . \ { } ( ) 等都具有特殊的含义,所以如果想要在正则中匹配这种特定的字符,需要进行转义,例如:

text = "我是你{5}爸爸"
data = re.findall("你{5}爸", text)
print(data)
>>输出结果:
[]
text = "我是你{5}爸爸"
data = re.findall("你\{5\}爸", text)
print(data)
>>输出结果:
["你{5}爸爸"]

1.3.2 re模块

python 中提供了 re 模块,可以处理正则表达式并对文本进行处理。

import re
1. findall:获取匹配到的所有数据,返回一个列表
text = "dsf130429191912015219k13042919591219521Xkk"
data_list = re.findall("(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)", text)
print(data_list) # [('130429', '1919', '12', '01', '521', '9'), ('130429', '1959', '12', '19', '521', 'X')]
2. match:从起始位置开始匹配,匹配成功返回一个特殊的对象,未匹配成功返回None
text = "大小逗2B最逗3B欢乐"
data = re.match("逗\dB", text)
print(data) # None

如果匹配成功,直接输出无法获取匹配的内容,可以通过 group() 获取 match 对象中匹配到的内容:

text = "逗2B最逗3B欢乐"
data = re.match("逗\dB", text)
print(data)
if data:content = data.group() # "逗2B"print(content)
>>输出结果:
<re.Match object; span=(0, 3), match='逗2B'>
逗2B
3. search:浏览整个字符串去匹配第一个,匹配成功返回一个特殊的对象,未匹配成功返回None
text = "大小逗2B最逗3B欢乐"
data = re.search("逗\dB", text)
if data:print(data.group())  # "逗2B"
>>输出结果:
<re.Match object; span=(2, 5), match='逗2B'>
逗2B
4. sub:替换匹配成功的位置
# 替换匹配成功的全部:
text = "逗2B最逗3B欢乐"
data = re.sub("\dB", "沙雕", text)
print(data)
>>输出结果:
逗沙雕最逗沙雕欢乐
# 替换匹配成功的第1个:
text = "逗2B最逗3B欢乐"
data = re.sub("\dB", "沙雕", text, 1)
print(data)
>>输出结果:
逗沙雕最逗3B欢乐
5. split:根据匹配成功的位置分割
# 根据匹配成功的位置全部进行分割:
text = "逗2B最逗3B欢乐"
data = re.split("\dB", text)
print(data)
>>输出结果:
['逗', '最逗', '欢乐']
# 根据匹配成功的第1个位置进行分割:
text = "逗2B最逗3B欢乐"
data = re.split("\dB", text, 1)
print(data)
>>输出结果:
['逗', '最逗3B欢乐']
6. finditer:匹配并返回一个迭代器,循环一次获取一个匹配成功的结果
text = "逗2B最逗3B欢乐"
data = re.finditer("\dB", text)
print(data)
for item in data:print(item.group())
>>输出结果:
<callable_iterator object at 0x0000021E9C0416A0>
2B
3B

通过 finditer 还可以对匹配成功后,分组提取的数据进行命名,例如:

# 分组命名格式:(?P<命名>正则)
text = "dsf130429191912015219k13042919591219521Xkk"
data_list = re.finditer("\d{6}(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})\d{3}[\d|X]", text)
for item in data_list:info_dict = item.groupdict()print(info_dict)
>>输出结果:
{'year': '1919', 'month': '12', 'day': '01'}
{'year': '1959', 'month': '12', 'day': '19'}

内置模块小结

到此,最常见的内置模块就全部介绍完了(共11个),现阶段只需要掌握这些模块的使用即可,其他的内置模块在后续的开发过程中遇到了再具体讲解。

  • os
  • shutil
  • sys
  • random
  • hashlib
  • configparser
  • xml
  • json
  • time
  • datetime
  • re

2. 项目开发规范

现阶段,我们在开发一些程序时(终端运行),应该遵循一些结构的规范,让你的项目更加专业。

2.1 单文件应用

当基于 python 开发简单应用时(一个 py 文件就能完成),需要注意如下几点规范:

2.2 单可执行文件

新创建一个项目,假设项目名称叫 " crm " ,可以创建如下文件和文件夹来存放代码和数据。

crm
├── app.py        文件,程序的主文件(尽量精简)
├── config.py     文件,配置文件(放相关配置信息,代码中读取配置信息,如果想要修改配置,可以在此修改,不用再去代码中逐一修改了)
├── db            文件夹,存放数据
├── files         文件夹,存放文件
├── src           包,业务处理的代码
└── utils         包,公共功能

示例:

2.3 多可执行文件

新创建项目,假设项目名叫 ’ killer ’ ,可以创建如下文件和文件夹来存放代码和数据。

killer
├── bin                 文件夹,存放多个主文件(可运行)
│   ├── app1.py
│   └── app2.py
├── config              包,配置文件
│   ├── __init__.py
│   └── settings.py
├── db                  文件夹,存放数据
├── files               文件夹,存放文件
├── src                 包,业务代码
│   └── __init__.py
└── utils               包,公共功能└── __init__.py

示例:

总结

  1. json 格式和 json 模块
  2. json 模块处理特殊的数据类型
  3. datetime 格式与字符串、时间戳以及相关之间的转换。
  4. datetime 格式时间与 timedelta 的加减。
  5. 两个 datetime 相减可以计算时间间隔,得到的是一个 timedelta 格式的时间。
  6. 了解正则表达式的编写方式和 python 中 re 模块的使用。
  7. 项目开发规范。

作业:开发短视频资讯平台(如需作业源码,可私信博主哈~)

  • 有video.csv视频库文件,其中有999条短视频数据,格式如下:【 video.csv 文件已为大家提供好,在day15课件目录下。 】

  • 项目的核心功能有:

    • 分页看新闻(每页显示10条),提示用户输入页码,根据页码显示指定页面的数据。

      • 提示用户输入页码,根据页码显示指定页面的数据。
      • 当用户输入的页码不存在时,默认显示第1页
    • 搜索专区

      • 用户输入关键字,根据关键词筛选出所有匹配成功的短视频资讯。
      • 支持的搜索两种搜索格式:
        • id=1715025,筛选出id等于1715025的视频(video.csv的第一列)。
        • key=文本,模糊搜索,筛选包含关键字的所有新闻(video.csv的第二列)。
    • 下载专区

      • 用户输入视频id,根据id找到对应的mp4视频下载地址,然后下载视频到项目的files目录。

        • 视频的文件名为:视频id-年-月-日-时-分-秒.mp4

        • 视频下载代码示例

          import requestsres = requests.get(url='https://video.pearvideo.com/mp4/adshort/20210105/cont-1715046-15562045_adpkg-ad_hd.mp4'
          )# 视频总大小(字节)
          file_size = int(res.headers['Content-Length'])download_size = 0
          with open('xxx.mp4', mode='wb') as file_object:# 分块读取下载的视频文件(最多一次读128字节),并逐一写入到文件中。 len(chunk)表示实际读取到每块的视频文件大小。for chunk in res.iter_content(128):download_size += len(chunk)file_object.write(chunk)file_object.flush()message = "视频总大小为:{}字节,已下载{}字节。".format(file_size, download_size)print(message)file_object.close()res.close()
          
        • 下载的过程中,输出已下载的百分比,示例代码如下:

          import timeprint("正在下载中...")
          for i in range(101):text = "\r{}%".format(i)print(text, end="")time.sleep(0.2)print("\n下载完成")
          

轩小陌的Python笔记-day15 内置模块(剩余)和开发规范相关推荐

  1. 轩小陌的Python笔记-day06 数据类型

    day06 数据类型(中) 常见的数据类型: int,整数类型(整形) bool,布尔类型 str,字符串类型 list,列表类型 tuple,元组类型 dict,字典类型 set,集合类型 floa ...

  2. 轩小陌的Python笔记-day14 自定义模块、第三方模块、内置模块(部分)

    day14 模块 课程目标:掌握Python中常用模块的使用方法. 今日概要: 自定义模块(包) 第三方模块 内置模块[1/2] 1. 自定义模块 1.1 模块和包 import hashlibdef ...

  3. 轩小陌的Python笔记-day13 匿名函数、生成器、内置函数、推导式

    day13 内置函数和推导式 今日概要: 匿名函数 生成器 内置函数 附加:推导式,属于数据类型的知识,内部的高级的用法会涉及到[生成器]和[函数]的内容. 1. 匿名函数 传统的函数的定义包括了:函 ...

  4. 轩小陌的Python笔记-day16 模块二总结

    day16 阶段总结 课程目标:对第二模块 "函数和模块" 阶段的知识点进行总结. 课程概要: 知识补充 阶段总结(思维导图) 1. 知识补充 1.1 nolocal关键字 在之前 ...

  5. 轩小陌的Python笔记-day25 MySQL入门

    第四模块 MySQL数据库 从今天开始将进入第四模块的学习,这个模块就是给大家讲解MySQL数据库. 以前,在开发程序时,我们会把很多的数据和信息存储到某个文件夹中的文件中,例如:user.txt . ...

  6. 轩小陌的Python笔记-day08 模块一总结

    day08 阶段总结和考试题 课程目标:对第一模块 "Python基础" 阶段的知识点进行总结,更好地掌握此模块的相关知识. 课程概要: 代码规范 知识补充 阶段总结(思维导图) ...

  7. 轩小陌的Python笔记-day28 索引、函数及存储过程

    day28 索引和函数及存储过程 课程目标:了解 MySQL 中索引.函数.存储过程.函数.触发器.视图等知识点. 课程概要: 索引 函数 存储过程 视图 触发器 1. 索引 在数据库中索引最核心的作 ...

  8. 轩小陌的Python笔记-day26 必备SQL语句、表关系及授权

    day26 必备SQL和表关系及授权 课程目标:掌握开发中最常见的SQL语句和表关系及授权相关知识点. 课程概要: 必备SQL(8个必备) 表关系 授权 1. 必备SQL语句 上一节讲解了最基础SQL ...

  9. 轩小陌的Python笔记-day05 数据类型

    day05 数据类型(上) 接下来的3篇的内容都是讲解数据类型的知识点,常见的数据类型: int,整数类型(整型) bool,布尔类型 str,字符串类型 list,列表类型 tuple,元组类型 d ...

最新文章

  1. Servlet的Web应用---三种方法获取表单的各种属性(源码)
  2. 图像显著区域检测代码及其效果图 saliency region detection
  3. XML表示的数据库数据
  4. linux 复制栈数据结构,算法-数据结构-堆栈
  5. 科比退役时间什么时候
  6. java 异常处理的关键字_java异常,异常处理,异常类 关键字:throws 和 throw 自定义的异常类...
  7. 【Java】 剑指offer(65) 不用加减乘除做加法
  8. 剪贴板增强工具 Ditto
  9. ctf xss利用_Csrf+Xss组合拳
  10. Learn Python the hard way, ex40 字典,可爱的字典
  11. Android-NDK 接入Fmod库,变声操作
  12. PCAN监测can总线状态设置
  13. HTTP协议5之代理--转
  14. iOS-图片可以自适应屏幕大小吗,应该会失真吧?
  15. 基于阿里云的API简介
  16. 空间数据库Topic推荐-AMiner
  17. Java面试——消息队列
  18. 用计算机演奏歌曲谱子,我要用计算器弹曲子,求亲们发点计算器简谱
  19. 计算机 学院派,总校计算机学院派老师来校召开“2+2”联合培养班学生见面会...
  20. 虹科Automation softPLC | 虹科KPA MoDK运行环境与搭建步骤(2)——MoDK运行环境搭建

热门文章

  1. 校园垃圾回收处理APP
  2. js 高级day04
  3. EdgeX Foundary 2.1Jakarta版官方文档中文翻译
  4. 四、nrf52832-蓝牙-定时器任务
  5. WMI基础知识(整理中)
  6. OCI学习-Storage:Block Volume
  7. 题解- [USACO09OCT]热浪Heat Wave
  8. python+django房屋出租租赁管理系统-含房东三个角色
  9. 新手学免杀之myccl使用指南
  10. 重庆南川中学2021高考成绩查询,重庆南川中学2021年录取分数线