模块索引

时间日期相关

from datetime import datetime, timedelta, timezone
from dateutil.relativedelta import *

# 创建时间对象
dt = datetime(2020, 1, 2, 12, 32, 12)
print(dt)

# 创建时间对象(当前时间)
dt = datetime.now()
print(dt)

# 创建时间对象(字符串)
dt = datetime.strptime('2020-1-2 12:32:12', '%Y-%m-%d %H:%M:%S')

# 格式化时间对象为字符串
print(dt.strftime('%Y-%m-%d %H:%M:%S'))

# 时间戳
timestamp = dt.timestamp()
print(timestamp)

# 创建时间对象(时间戳)
print(datetime.fromtimestamp(timestamp))

# 输出时间对象相关信息(以天、分、日期为例)
print(dt.day)
print(dt.minute)
print(dt.date())

# 时间加减 timedelta(最大的操作单位是周)
print(dt - timedelta(days=3))
print(dt - timedelta(weeks=1))

# 如果需要用年或月作单位,可以使用relativedelta
print(dt - relativedelta(years=1))
print(dt + relativedelta(months=1))
# 下个月的最后一天,这里的31表示该月的最后一天,如果是2月,其值为:28或29
print(dt + relativedelta(months=1) + relativedelta(day=31))

# 拿到UTC时间,并强制设置时区为UTC+0:00(设置基准时间)
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt)

# 基于基准时间转换时区
bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S')
print(bj_dt)

正则

import re

# 匹配会返回match对象,否则返回None
res = re.match(r'^\d+$', '123')
print(res)

# 切分字符串
res = re.split(r'\s+', 'a b            c')
print(res)

# 分组
res = re.match(r'^(ab).*?(aa).*?$', 'abcdaabcdefg')
print(res.groups())

# 预编译,复用规则
allNum = re.compile(r'^\d+$')
print(allNum.match('123'))
print(allNum.match('456'))

base64编码

import base64
from urllib import parse

# base64编码
encode = base64.b64encode(b'test')
# bytes to str
print(encode.decode())

# base64解码
decode = base64.b64decode(encode)
print(decode.decode())

# url安全的base64编码
urlSaveEncode = base64.urlsafe_b64encode(b'test')
print(urlSaveEncode.decode())

# url安全的base64解码
urlSaveDecode = base64.urlsafe_b64decode(urlSaveEncode)
print(urlSaveDecode.decode())

hashlib

md5、sha1等都封装在hashlib库中

import hashlib

# md5签名
md5 = hashlib.md5()
md5.update('test'.encode('utf-8'))
test1 = md5.hexdigest()
print(test1)

# 字符串长,可以多次调用update()
md5 = hashlib.md5()
md5.update('te'.encode('utf-8'))
md5.update('st'.encode('utf-8'))
test2 = md5.hexdigest()
print(test2)
print(test1 == test2)

# sha1签名
sha1 = hashlib.sha1()
sha1.update('te'.encode('utf-8'))
sha1.update('st'.encode('utf-8'))
test3 = sha1.hexdigest()
print(test3)

hmac

import hmac

h = hmac.new(b'salt', b'test', digestmod='md5')
print(h.hexdigest())

itertools

itertools是一个"无限"迭代器工具

import itertools

# 输出 1-10
for i in itertools.count(1):
    print(i)
    if i >= 10:
        break

# 使用 takewhile 只要 1-10
i = itertools.count(1)
nums = itertools.takewhile(lambda x: x <= 10, i)
print(list(nums))

# 无限重复一个序列
for i in itertools.cycle('string'):
    print(i)

# 无限重复一个元素,第2个参数可控制重复的次数
for i in itertools.repeat('string', 3):
    print(i)

# 串联一组迭代对象
for i in itertools.chain('abc', 'def'):
    print(i)

# 把迭代器中相邻的重复元素挑出来放在一起,注意:必须是相邻
for key, group in itertools.groupby('aabbccabc'):
    print(key, list(group))

# 根据首字母分组
first_letter = lambda x: x[0]
names = ["Alex", "Alan", "Adam", "Linda", "Mary", "Json", "Jerry", "Make"]
for k, group in itertools.groupby(names, first_letter):
    print(k, list(group))

# 组合
for i, j, k in itertools.combinations(names, 3):
    print(i, j, k)

# 排列
for i, j in itertools.permutations(names, 2):
    print(i, j)

urllib库

from urllib import request
from urllib import parse

# GET
response = request.urlopen("http://www.baidu.com", timeout=3)
print(response.read().decode("utf-8"))

# POST
data = bytes(parse.urlencode({'phone': '13585530888', 'password': '123456'}), encoding='utf8')
response = request.urlopen('http://127.0.0.1:9501', data=data, timeout=3)
print(response.read().decode('utf-8'))

pathlib

Python3.4添加了新的模块pathlib,它使用面向对象的编程方式来表示文件系统路径

部分文件系统也使用了pathlib一致的接口,建议用pathlib来替代os

from pathlib import Path, PurePath
import shutil

# 获取当前目录
print(Path.cwd())

# 路径拼接
print(Path.cwd().joinpath("test.py"))
print(Path.cwd() / Path("test.py"))

# 获取基础名
print(Path.cwd() / Path("test.py").name)

# 获取扩展名
print((Path.cwd() / Path("test.py")).suffix)

# 获取基础名不带扩展
print((Path.cwd() / Path("test.py")).stem)

# 获取多个扩展名,如:xxx.tar.gz
print((Path.cwd() / Path("xxx.tar.gz")).suffixes)

# 是否是路径
print(Path("./test").is_dir())

# 是否是文件
print(Path("./test").is_file())

# 创建路径
Path("./test1/test2/test3").mkdir(parents=True)

# 创建文件
Path("./test1/test1.log").touch()

# 写入内容到文件
with Path("./test1/test1.log").open(mode='a') as fp:
    fp.write("test content" + os.linesep)

# 重命名文件
Path("./log/customer/aaa/test/test1.log").rename(Path("./log/customer/aaa/test/test2.log"))

# 复制文件
shutil.copy(Path("./log/customer/aaa/test/test.log"), Path("./log/customer/aaa/test/test3.log"))

# 上级目录
print(Path.cwd().parent)

# 读取文件内容
print(Path.cwd().joinpath("test.py").read_text())

# 遍历当前路径
for i in Path.cwd().iterdir():
    print(i)

# 遍历当前路径下所有的py文件
files = [i for i in Path.cwd().iterdir() if PurePath(i).match("*.py")]
print(files)

# 遍历当前路径以及所有的子路径
# **匹配0个或多个目录及子目录,不包含.和..开头的
print(list(Path.cwd().joinpath("test").glob("**/*")))

# rglob从右边开始匹配,通常用于扩展名的匹配
print(list(Path.cwd().joinpath("test").rglob("**/*.pdf")))

subprocess

调用外部命令,可以使用subprocess模块

Python之所以被称为最佳的“胶水语言”,就是因为它能轻易“粘合”可执行程序

from subprocess import run, Popen, PIPE

cmd1 = ["ls", "."]

# 调用run会直接执行ls命令,会直接输出ls的结果
# 输出返回码,CompletedProcess(args=['ls', '.'], returncode=0)
print(run(cmd1))

# 使用Popen获取程序运行结果,不会直接输入ls的结果
with Popen(cmd1, shell=True, stdout=PIPE, stderr=PIPE, encoding="utf-8") as fs:
    # 如果程序在 timeout 秒后未执行完成,会抛出 TimeoutExpired 异常
    fs.wait(2)
    # 从标准输出中读取数据,直到文件结束
    files = fs.communicate()[0]

# 这里的print才是真正输出ls的内容
print(files)

压缩与解压缩带密码的zip文件

from subprocess import run
from pathlib import Path

cmd1 = ["zip", "-r", "-P", "123456", "test.zip", Path.cwd().joinpath("log")]
run(cmd1)
cmd2 = ["unzip", "-P", "123456", "test.zip"]
run(cmd2)

argparse

命令行配置选项

import argparse


def args_opt():
    """获取命令行参数函数"""

    # 定义参数对象
    parser = argparse.ArgumentParser()

    # 增加参数选项、是否必须、帮助信息
    parser.add_argument("-p", "--path", required=True, help="请输入执行路径")
    parser.add_argument("-f", "--file", required=True, help="请输入执行文件")

    # 返回取得的所有参数
    return parser.parse_args()


if __name__ == "__main__":
    # args 对象包含所有参数,属性是命令行参数的完整名称
    args = args_opt()
    print(args.path)
    print(args.file)

bisect

bisect可以对有序数组做一些二分操作(相对效率较高)

bisect不会检查列表是否已排序,因为这样代价太大。如果对未排序的列表使用bisect相关函数不会报错,但是可能导致不正确的结果

bisect.insort默认是升序的,如果需要倒序,可以乘以-1,等使用的时候再乘以-1

import bisect

# 必须是有序数组
a = [1, 2, 2, 2, 3, 4, 5, 7]

# 找到元素应当被插入的位置(如果有重复元素,会返回后面的位置)
print(bisect.bisect(a, 2))  # 4
print(a)  # [1, 2, 2, 2, 3, 4, 5, 7]

# 将元素插入到对应的位置
print(bisect.insort(a, 2))  # None
print(a)  # [1, 2, 2, 2, 2, 3, 4, 5, 7]

results matching ""

    No results matching ""