Python 【工具推荐】自己封装的 python 常用工具库(prestool)

霜序五 · February 22, 2022 · Last by 霜序五 replied at March 02, 2022 · 10349 hits

Downloads

一、安装(python 版本建议 3.7 以上)

pip install --upgrade  prestool

二、常用工具

from prestool.Tool import Tool

tool = Tool()

随机数据

tool.random_name()  # 随机姓名
tool.random_phone()  # 随机手机号
tool.random_ssn()  # 随机身份证

tool.random_string(16)  # 随机位数的字符串
tool.random_number(8)  # 随机位数的数字

tool.random_ua()  # 随机UA
tool.random_ua('chrome')  # 随机UA-Chrome
tool.random_ua('firefox')  # 随机UA-Firefox
tool.random_ua('ie')  # 随机UA-IE
tool.random_ua('opera')  # 随机UA-opera
tool.random_ua('safari')  # 随机UA-safari

编码解码

tool.url_encode('编码前的url地址')  # 编码
tool.url_decode('解码前的url地址')  # 解码

tool.base_64_encode('编码前的字符串')  # base64编码

加密相关

tool.to_md5('原始字符串')
tool.to_hmac_256('原始字符串', '加密key')
tool.to_sha_256('原始字符串')

发送消息

钉钉
tool.ding_talk_token = '钉钉机器人token'
tool.ding_talk_sign_key = '钉钉机器人签名key'

tool.send_ding_talk_msg('消息内容')
企业微信
tool.qy_wechat_token = '企业微信机器人token'

tool.send_qy_wechat_msg('消息内容')
飞书
tool.feishu_token = '飞书机器人token'
tool.feishu_sign_key = '飞书机器人秘钥'

tool.send_feishu_msg('消息内容')
邮件
tool.mail_from_user_host = '发件地址host'
tool.mail_from_user = '发件人邮箱号'
tool.mail_from_user_pwd = '发件人密码'

tool.send_mail_msg(to_user='收件人邮箱地址(列表)', title='邮件标题', content='邮件内容')

时间相关

tool.time_stamp()  # 秒级时间戳10位
tool.time_stamp('ms')  # 毫秒级时间戳13位

tool.get_now_time()  # 获取当前时间 20201206000000
tool.get_now_time('-')  # 获取当前时间 2020-12-06 00:00:00

tool.date_to_time_stamp('2012-01-01 00:00:00')  # 时间字符串转为时间戳
tool.time_stamp_to_date(1732312234)  # 时间戳转为时间字符串

格式转换

tool.json_dumps({"test": "python字典"})  # 字典转json
tool.json_loads('{"test": "python字典"}')  # json转字典
tool.xml_to_dict('<xml><data>字符串</data></xml>')  # xml转成python字典
tool.dict_to_xml({"test": "python字典"})  # python字典 转成xml

http请求

tool.http_client(url='', data={}, method='GET')  # get请求
tool.http_client(url='', data={}, method='POST')  # post请求

tool.get_cookies(url='接口地址', data={}, method='GET')
tool.get_cookies(url='接口地址', data={}, method='POST')

tool.trans_data_to_url(url='接口地址', data={})  # 把参数拼接到url上

dubbo接口

tool.dubbo_args('参数1', '参数2', '参数3')  # dubbo接口参数
tool.invoke_dubbo('地址', '端口', '服务API名', '接口方法名', 'dubbo接口参数')  # 请求dubbo接口

其他

tool.logger('日志信息')
tool.get_ip_by_url('url地址')  # 获取ip

三、数据库语句(MySQL/Sqlite

一、生成数据库sql语句

from prestool.PresMySql import SqlStr

sql = SqlStr()
查询语句
target不传时,为全部字段,即*where={'key':'value'}
sql.select_sql_str(table='table1', where={'id': 1, 'name': '张三'})
select * from table1 where id = 1 and name = '张三';
target=[i1,i2,i3]时,为相应字段
sql.select_sql_str(table='table1', target=['a', 'b', 'c'], where={'id': 1, 'name': '张三'})
select a, b, c from table1 where 1 = 1 and id = 1 and name = '张三';
limit=10 limit='10,1000'为筛选限制字段
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    order={'age': 'desc', 'score': 'desc'}, 
    limit=20)
select a, b, c from table1 where 1 = 1 order by age desc, score desc limit 20;
where条件中有的字段为null或者not null
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    where={'id': 1}, 
    is_not_null={'age': True, 'name': None})
select a, b, c from table1 where 1 = 1 and id = 1 and age is not null and name is null;
支持排序语句
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    order={'age': 'desc', 'score': 'desc'})
select a, b, c from table1 order by age desc, score desc;
支持查询in语句
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    select_in={'orders': [123121312, 123123445, 213123]})
支持查询not in语句
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    select_not_in={'orders': [123121312, 123123445, 213123]})
select a, b, c from table1 where 1 = 1 and orders not in (123121312, 123123445, 213123);
支持like语句
sql.select_sql_str(table='table1', target=['a', 'b', 'c'], like={'name': '%光', 'address': "中国%"})
select a, b, c from table1 where 1 = 1 and name like '%光' and address like '中国%';
支持between语句
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'], 
    between={'age': (10, 20), 'year': (2021, 2022)})
select a, b, c from table1 where 1 = 1 and age between 10 and 20 and year between 2021 and 2022;
支持大于、小于语句
sql.select_sql_str(
    table='table1', 
    target=['a', 'b', 'c'],                  
    compare={'age': {'>': 10, '<': 20}, 'year': {'>=': '2021'}})
select a, b, c from table1 where 1 = 1 and age > 10 and age < 20 and year >= 2021;
更新语句
target为要更新的数据,为字典结构 (支持大于、小于语句、between 语句、like 语句、in 语句)
sql.update_sql_str(table='table1', target={'name': '李四', 'age': 15}, where={'id': 1, 'name': '张三'}) 
update table1 set name='李四',age=15 where id = 1 and name = '张三';
删除数据
支持大于、小于语句、between 语句、like 语句、in 语句
sql.delete_sql_str(table='table1', where={'id': 1, 'name': '张三'})
delete from table1 where id = 1 and name = '张三';
插入数据
sql.insert_sql_str(table='table1', target={'id': 1, 'name': '张三'})
insert into table1 (id, name) values (1, '张三');

二、执行数据库语句

mysql模式
from prestool.PresMySql import PresMySql

pres = PresMySql()
sqlite模式
from prestool.PresSqlite import PresSqlite

pres = PresSqlite()
初始化数据库信息
mysql 模式
pres.mysql_host = ''
pres.mysql_port = 3306
pres.mysql_user = ''
pres.mysql_pwd = ''
pres.mysql_db_name = ''
pres.mysql_charset = 'utf8mb4'
sqlite 模式
pres.sqlite_path = ''
执行相应语句即可,执行的方法参数等同于第三节所述的 sql 语句,如
pres.to_query(table='table1', target=['a', 'b', 'c'], between={'age': (10, 20), 'year': (2021, 2022)})

pres.to_insert(table='table1', target={'id': 1, 'name': '张三'})

pres.to_delete(table='table1', where={'id': 1, 'name': '张三'})

pres.to_update(table='table1', target={'name': '李四', 'age': 15}, where={'id': 1, 'name': '张三'})
参数化查询(推荐,防止 SQL 注入)
生成参数化 SQL 语句
from prestool.PresMySql import SqlStr

sql = SqlStr()

# INSERT 参数化
sql_str, values = sql.insert_sql_str_params(table='table1', target={'id': 1, 'name': "O'Brien"})
# 返回: ('INSERT INTO table1 (id, name) VALUES (%s, %s)', [1, "O'Brien"])

# UPDATE 参数化
sql_str, values = sql.update_sql_str_params(table='table1', target={'name': "O'Brien"}, where={'id': 1})
# 返回: ('UPDATE table1 SET name = %s WHERE id = %s', ["O'Brien", 1])

# DELETE 参数化
sql_str, values = sql.delete_sql_str_params(table='table1', where={'id': 1, 'name': "O'Brien"})
# 返回: ('DELETE FROM table1 WHERE id = %s AND name = %s', [1, "O'Brien"])
直接执行参数化操作
from prestool.PresMySql import PresMySql

pres = PresMySql()
# ... 初始化数据库连接 ...

# 参数化 INSERT(自动处理特殊字符,防止 SQL 注入)
pres.to_insert_params(table='table1', target={'id': 1, 'name': "O'Brien"})

# 参数化 UPDATE
pres.to_update_params(table='table1', target={'name': "O'Brien"}, where={'id': 1})

# 参数化 DELETE
pres.to_delete_params(table='table1', where={'id': 1, 'name': "O'Brien"})

# 自定义参数化 SQL
pres.exec_sql('SELECT * FROM table1 WHERE name = %s', select='all', args=["O'Brien"])

注意:

  • to_query 方法始终返回 list[dict],空结果返回 []
  • 参数化查询使用 %s 作为占位符(SQLite 会自动转换为 ?

四、数据库语句(MongoDB)

一、执行数据库语句

from prestool.PresMongo import PresMongo

pres = PresMongo()
初始化数据库信息
pres.mongo_host = ''
pres.mongo_port = 27017
pres.mongo_user = ''
pres.mongo_pwd = ''
pres.mongo_db_name = ''
pres.mongo_auth_source = ''
查询语句 (默认查询一条,查询多条可使用 is_all=True)
普通查询
pres.to_query(table='abc', where={'id': "123123"})
pres.to_query(table='abc', where={'$and': [{'age': 14}, {'sex': 1}]})

res = pres.to_query(table='abc', where={'id': "123123"}, is_all=True)
for i in res:
    print(i)
排序
pres.to_query(table='abc', where={'id': "123123"}, asc='age')  # 按年龄正序
pres.to_query(table='abc', where={'id': "123123"}, desc='age')  # 按年龄倒序
数量限制
pres.to_query(table='abc', where={'id': "123123"}, limit=10) 

更新语句

pres.to_update(table='abc', target={'age': 14}, where={'name': '张三'})

插入语句

pres.to_insert(table='abc', target={'age': 14})  # 插入一条
pres.to_insert(table='abc', target=[{'age': 14}, {"name": '张三'}])  # 插入一个列表

五、操作缓存(Redis)

一、连接Redis

from prestool.PresRedis import PresRedis

pres = PresRedis()

二、初始化redis

pres.redis_host = 'localhost'      # Redis 地址
pres.redis_port = 6379            # Redis 端口
pres.redis_password = None        # 密码(可选)
pres.redis_db = 0                 # 数据库编号(可选)

三、String 操作

# 设置值(ex=过期秒数)
pres.set('key', 'value', ex=3600)

# 获取值
value = pres.get('key')

# 检查键是否存在
exists = pres.exists('key')

# 删除键
pres.delete('key')

# 设置过期时间
pres.expire('key', 7200)

# 获取剩余 TTL
ttl = pres.ttl('key')

# 原子递增/递减
pres.incr('counter')      # +1
pres.decr('counter', 5)   # -5

四、JSON 操作

# 存储 JSON(自动序列化)
data = {'name': '张三', 'age': 25, 'roles': ['admin', 'editor']}
pres.set_json('user:1', data, ex=7200)

# 读取 JSON(自动反序列化)
result = pres.get_json('user:1')

五、Hash 操作

# 设置字段
pres.hset('user:profile', 'nickname', '张三')
pres.hset('user:profile', 'level', 'VIP')

# 获取单个字段
nickname = pres.hget('user:profile', 'nickname')

# 批量设置
pres.hmset('user:profile', {'phone': '13800138000', 'email': 'test@example.com'})

# 获取所有字段
profile = pres.hgetall('user:profile')
# 返回: {'nickname': '张三', 'level': 'VIP', 'phone': '13800138000', 'email': 'test@example.com'}

# 检查字段存在
has_level = pres.hexists('user:profile', 'level')

# 获取字段数量
field_count = pres.hlen('user:profile')

# 获取所有字段名/字段值
fields = pres.hkeys('user:profile')
values = pres.hvals('user:profile')

# 删除字段
pres.hdel('user:profile', 'level')

六、List 操作

# 头部/尾部插入
pres.lpush('queue', 'task1', 'task2')
pres.rpush('queue', 'task3')

# 头部/尾部弹出
task = pres.lpop('queue')
task = pres.rpop('queue')

# 获取列表长度
length = pres.llen('queue')

# 获取范围元素
items = pres.lrange('queue', 0, 9)  # 前10个

七、Set 操作

# 添加成员
pres.sadd('tags', 'python', 'redis', 'cache')

# 获取所有成员
members = pres.smembers('tags')

# 检查成员
is_member = pres.sismember('tags', 'python')

# 移除成员
pres.srem('tags', 'cache')

# 成员数量
count = pres.scard('tags')

八、批量操作

# 按模式扫描删除(推荐)
pres.scan_delete('cache:*')
pres.scan_delete('session:*')

# 获取匹配的所有键(慎用,影响性能)
keys = pres.keys('user:*')

# 迭代获取键(生产环境推荐)
for key in pres.scan_iter('cache:*'):
    print(key)

# 清空当前数据库(危险!)
pres.flushdb()

九、原生操作

# 直接使用 StrictRedis 实例
with pres.conn_redis() as r:
    r.set('raw:key', 'raw:value')
    r.get('raw:key')
上传到 pypi 相关
uv build
uv publish
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 15 条回复 时间 点赞

挺好的,虽然对其他人来说可能并不适用,但是方式方法值得学习

使用起来有点类似 tp 的 model 类,瞬间上手🙀

真棒 我借鉴一下

lazyBoy 回复

恩恩。感谢支持。最一开始就是写来自己用的。后来就直接干脆放到 pypi 上了,写一些工具和脚本的时候可以直接拿起来用。

在下松岗 回复

谢谢支持~~

Mini-Right 回复

谢谢

真好用,点赞👍

爪印🐾 回复

谢谢支持~

点赞

霜序五 #12 · March 01, 2022 Author

因为你的这个 py 文件名跟我的 module 重名了。把你这个文件重命名一下就行了

霜序五 #13 · March 01, 2022 Author

谢谢~

👍 自己的项目都是写了一些自己用的类方法,你这种方式都没想到过,学习下

霜序五 #15 · March 02, 2022 Author
小L 回复

互相学习

兔子🐰 2022 第二季度 社区活跃用户获奖名单 中提及了此贴 07 Jul 10:37
17Floor has deleted
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up