2-7 内置模块和项目规范

 概要:

  • 内置模块

    • json

    • time

    • datetime

    • re

  • 开发规范

    • 主文件

    • 配置文件

    • 数据

 

 

1. 内置模块

 

1.1 json

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

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

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

 

1.1.1 核心功能

 

json格式的作用?

跨语言数据传输,例如:
    A系统用Python开发,有列表类型和字典类型等。
    B系统用Java开发,有数组、map等的类型。
​
    语言不同,基础数据类型格式都不同。
    
    为了方便数据传输,大家约定一个格式:json格式,每种语言都是将自己数据类型转换为json格式,也可以将json格式的数据转换为自己的数据类型。

 

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

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

    import json
    ​
    data = [
        {"id": 1, "name": "ayden", "age": 18},
        {"id": 2, "name": "alex", "age": 18},
    ]
    ​
    res = json.dumps(data)
    print(res) # '[{"id": 1, "name": "ayden", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'
    ​
    res = json.dumps(data, ensure_ascii=False)
    print(res) # '[{"id": 1, "name": "ayden", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'

     

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

    import json
    ​
    data_string = '[{"id": 1, "name": "ayden", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'
    ​
    data_list = json.loads(data_string)
    ​
    print(data_list)

     

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": "ayden", "age": 18},
    {"id": 2, "name": "alex", "age": 18},
]

其他类型如果想要支持,需要自定义JSONEncoder才能实现,例如:

import json
from decimal import Decimal
from datetime import datetime
​
data = [
    {"id": 1, "name": "ayden", "age": 18, 'size': Decimal("18.99"), 'ctime': datetime.now()},
    {"id": 2, "name": "alex", "age": 18, 'size': Decimal("9.99"), 'ctime': datetime.now()},
]
​
​
class MyJSONEncoder(json.JSONEncoder):
    def default(self, o):
        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.dumps,序列化生成一个字符串。

  • json.loads,发序列化生成python数据类型。

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

    import json
    ​
    data = [
        {"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 json
    ​
    file_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
​
# 获取当前时间戳(自1970-1-1 00:00)
v1 = time.time()
print(v1)
​
# 时区
v2 = time.timezone
​
# 停止n秒,再执行后续的代码。
time.sleep(5)

 

1.2.2 datetime

在平时开发过程中的时间一般是以为如下三种格式存在:

  • datetime

    from datetime import datetime, timezone, timedelta
    ​
    v1 = datetime.now()  # 当前本地时间
    print(v1)
    ​
    tz = timezone(timedelta(hours=7))  # 当前东7区时间
    v2 = datetime.now(tz)
    print(v2)
    ​
    v3 = datetime.utcnow()  # 当前UTC时间
    print(v3)
    from datetime import datetime, timedelta
    ​
    v1 = datetime.now()
    print(v1)
    ​
    # 时间的加减
    v2 = v1 + timedelta(days=140, minutes=5)
    print(v2)
    ​
    # datetime类型 + timedelta类型
    from datetime import datetime, timezone, timedelta
    ​
    v1 = datetime.now()
    print(v1)
    ​
    v2 = datetime.utcnow()  # 当前UTC时间
    print(v2)
    ​
    # datetime之间相减,计算间隔时间(不能相加)
    data = v1 - v2
    print(data.days, data.seconds / 60 / 60, data.microseconds)
    ​
    # datetime类型 - datetime类型
    # datetime类型 比较 datetime类型

     

  • 字符串

    # 字符串格式的时间  ---> 转换为datetime格式时间
    text = "2021-11-11"
    v1 = datetime.strptime(text,'%Y-%m-%d') # %Y 年,%m,月份,%d,天。
    print(v1)
    # datetime格式 ----> 转换为字符串格式
    v1 = datetime.now()
    val = v1.strftime("%Y-%m-%d %H:%M:%S")
    print(val)

     

  • 时间戳

    # 时间戳格式 --> 转换为datetime格式
    ctime = time.time() # 11213245345.123
    v1 = datetime.fromtimestamp(ctime)
    print(v1)
    # datetime格式 ---> 转换为时间戳格式
    v1 = datetime.now()
    val = v1.timestamp()
    print(val)

     

 

1.3 正则表达式相关

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

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

 

1.3.1 正则表达式

1. 字符相关

 

  • [abc] 匹配a或b或c 字符。

    import re
    ​
    text = "你2b好wupeiqi,阿斯顿发awupeiqasd 阿士大夫a能接受的wffbbupqaceiqiff"
    data_list = re.findall("[abc]", text)
    print(data_list) # ['b', 'a', 'a', 'a', 'b', 'b', 'c']
    import re
    ​
    text = "你2b好wupeiqi,阿斯顿发awupeiqasd 阿士大夫a能接受的wffbbupqcceiqiff"
    data_list = re.findall("q[abc]", text)
    print(data_list) # ['qa', 'qc']

     

  • [^abc] 匹配除了abc意外的其他字符。

    import re
    ​
    text = "你wffbbupceiqiff"
    data_list = re.findall("[^abc]", text)
    print(data_list)  # ['你', 'w', 'f', 'f', 'u', 'p', 'e', 'i', 'q', 'i', 'f', 'f']

     

  • [a-z] 匹配a~z的任意字符( [0-9]也可以 )。

    import re
    ​
    text = "alexrootrootadmin"
    data_list = re.findall("t[a-z]", text)
    print(data_list)  # ['tr', 'ta']

     

  • . 代指除换行符以外的任意字符。

    import re
    ​
    text = "alexraotrootadmin"
    data_list = re.findall("r.o", text)
    print(data_list) # ['rao', 'roo']
    import re
    ​
    text = "alexraotrootadmin"
    data_list = re.findall("r.+o", text) # 贪婪匹配
    print(data_list) # ['raotroo']
    import re
    ​
    text = "alexraotrootadmin"
    data_list = re.findall("r.+?o", text) # 非贪婪匹配
    print(data_list) # ['rao']

     

  • \w 代指字母或数字或下划线(汉字)。

    import re
    ​
    text = "北京武沛alex齐北  京武沛alex齐"
    data_list = re.findall("武\w+x", text)
    print(data_list) # ['武沛alex', '武沛alex']

     

  • \d 代指数字

    import re
    ​
    text = "root-ad32min-add3-admd1in"
    data_list = re.findall("d\d", text)
    print(data_list) # ['d3', 'd3', 'd1']
    import re
    ​
    text = "root-ad32min-add3-admd1in"
    data_list = re.findall("d\d+", text)
    print(data_list) # ['d32', 'd3', 'd1']

     

  • \s 代指任意的空白符,包括空格、制表符等。

    import re
    ​
    text = "root admin add admin"
    data_list = re.findall("a\w+\s\w+", text)
    print(data_list) # ['admin add']

     

2. 数量相关
  • * 重复0次或更多次

    import re
    ​
    text = "他是大B个,确实是个大2B。"
    data_list = re.findall("大2*B", text)
    print(data_list) # ['大B', '大2B']

     

  • + 重复1次或更多次

    import re
    ​
    text = "他是大B个,确实是个大2B,大3B,大66666B。"
    data_list = re.findall("大\d+B", text)
    print(data_list) # ['大2B', '大3B', '大66666B']

     

  • ? 重复0次或1次

    import re
    ​
    text = "他是大B个,确实是个大2B,大3B,大66666B。"
    data_list = re.findall("大\d?B", text)
    print(data_list) # ['大B', '大2B', '大3B']

     

  • {n} 重复n次

    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("151312\d{5}", text)
    print(data_list) # ['15131255789']

     

  • {n,} 重复n次或更多次

    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("\d{9,}", text)
    print(data_list) # ['442662578', '15131255789']
    ​

     

  • {n,m} 重复n到m次

    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("\d{10,15}", text)
    print(data_list) # ['15131255789']

     

 

3. 括号(分组)
  • 提取数据区域

    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("15131(2\d{5})", text)
    print(data_list)  # ['255789']
    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来15131266666呀"
    data_list = re.findall("15(13)1(2\d{5})", text)
    print(data_list)  # [ ('13', '255789')   ]
    
    
    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("(15131(2\d{5}))", text)
    print(data_list)  # [('15131255789', '255789')]

     

  • 获取指定区域 + 或条件

    import re
    ​
    text = "楼主15131root太牛15131alex逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    data_list = re.findall("15131(2\d{5}|r\w+太)", text)
    print(data_list)  # ['root太', '255789']
    import re
    ​
    text = "楼主15131root太牛15131alex逼了,在线想要 442662578@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,}
  2. 身份证号码

    import re
    ​
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("\d{17}[\dX]", text) # [abc]
    print(data_list) # ['130429191912015219', '13042919591219521X']
    import re
    ​
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("\d{17}(\d|X)", text)
    print(data_list) # ['9', 'X']
    import re
    ​
    text = "dsf130429191912015219k13042919591219521Xkk"
    data_list = re.findall("(\d{17}(\d|X))", text)
    print(data_list) # [('130429191912015219', '9'), ('13042919591219521X', 'X')]

     

  3. 手机号

    import re
    ​
    text = "我的手机哈是15133377892,你的手机号是1171123啊?"
    data_list = re.findall("1[3-9]\d{9}", text)
    print(data_list)  # ['15133377892']

     

  4. 邮箱地址

    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("\w+@\w+\.\w+",text)
    print(email_list) # ['442662578@qq.com和xxxxx']
    import re
    ​
    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)
    print(email_list) # ['442662578@qq.com', 'xxxxx@live.com']
    ​
    import re
    ​
    text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
    email_list = re.findall("\w+@\w+\.\w+", text, re.ASCII)
    print(email_list) # ['442662578@qq.com', 'xxxxx@live.com']
     

 

4. 起始和结束

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

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

  • ^ 开始

  • $ 结束

import re
​
text = "啊442662578@qq.com我靠"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list) # []
import re
​
text = "442662578@qq.com"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list) # ['442662578@qq.com']

 

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

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

 

5. 特殊字符

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

import re
​
text = "我是你{5}爸爸"
data = re.findall("你{5}爸", text)
print(data) # []
import re
​
text = "我是你{5}爸爸"
data = re.findall("你\{5\}爸", text)
print(data)

 

1.3.2 re模块

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

  • findall,获取匹配到的所有数据

    import re
    ​
    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')]

     

  • match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None

    import re
    ​
    text = "大小逗2B最逗3B欢乐"
    data = re.match("逗\dB", text)
    print(data) # None
    import re
    ​
    text = "逗2B最逗3B欢乐"
    data = re.match("逗\dB", text)
    if data:
        content = data.group() # "逗2B"
        print(content)

     

  • search,浏览整个字符串去匹配第一个,未匹配成功返回None

    import re
    ​
    text = "大小逗2B最逗3B欢乐"
    data = re.search("逗\dB", text)
    if data:
        print(data.group())  # "逗2B"

     

  • sub,替换匹配成功的位置

    import re
    ​
    text = "逗2B最逗3B欢乐"
    data = re.sub("\dB", "沙雕", text)
    print(data) # 逗沙雕最逗沙雕欢乐
    import re
    ​
    text = "逗2B最逗3B欢乐"
    data = re.sub("\dB", "沙雕", text, 1)
    print(data) # 逗沙雕最逗3B欢乐

     

  • split,根据匹配成功的位置分割

    import re
    ​
    text = "逗2B最逗3B欢乐"
    data = re.split("\dB", text)
    print(data) # ['逗', '最逗', '欢乐']
    import re
    ​
    text = "逗2B最逗3B欢乐"
    data = re.split("\dB", text, 1)
    print(data) # ['逗', '最逗3B欢乐']

     

  •  

""" 函数注释 """ ​    # TODO 待完成时,下一期实现xxx功能    for i in range(10):        pass ​ ​ def run():    """ 函数注释 """ ​    # 对功能代码进行注释    text = input(">>>")    print(text) ​ ​ if __name__ == '__main__':    run()

 

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

 

 

 

posted @ 2023-11-30 16:26  晴朗sky  阅读(29)  评论(0)    收藏  举报