Python技术迷

7个Python库,快速搞定公司内部工具

Excel 一来,需求基本就定了:导个表、清字段、调个内部接口、跑一遍校验、最后再吐个结果文件。公司里很多“内部工具”,说白了不是大系统,就是一把趁手的小刀。真别上来就 Flask、Django 全家桶,十有八九写重了。

我平时更喜欢这么配,7 个 Python 库,够快,够脏活累活,也够落地。

1. typer:先把脚手架立起来

内部工具最怕什么?不是功能少,是入口乱。有人双击 py,有人改代码里的变量,有人传参传错还说脚本坏了。

typer 这类 CLI 库很适合做公司里的批处理工具:

import typer
from pathlib import Path

app = typer.Typer()

@app.command()
defrun(file: Path, env: str = "test"):
    print(f"开始处理: {file}, 环境: {env}")

if __name__ == "__main__":
    app()

这东西的好处很直接:参数规范,帮助信息自动带出来,发给测试和运营也不至于一运行就懵。

2. pydantic:别让脏数据进来再炸

很多内部工具不是逻辑难,是输入太脏。Excel 里手机号带空格,金额是字符串,日期还混着斜杠和短横线。你不先拦,后面全是屎。

from pydantic import BaseModel, field_validator

classUserRow(BaseModel):
    user_id: int
    mobile: str
    amount: float

    @field_validator("mobile")
    @classmethod
defclean_mobile(cls, v: str):
        v = v.strip().replace(" ", "")
if len(v) != 11ornot v.isdigit():
raise ValueError("手机号格式不对")
return v

这一步我一般放得很靠前。先验数据,再谈业务。别一边调用接口一边发现第 327 行手机号错了。

3. pandas:表格清洗这活,它干得比人稳

只要碰导入导出,pandas 基本跑不掉。尤其是对账、补数据、批量比对这种活,靠 for 循环硬搓,写着就累。

import pandas as pd

df = pd.read_excel("退款名单.xlsx")
df["订单号"] = df["订单号"].astype(str).str.strip()
df["退款金额"] = pd.to_numeric(df["退款金额"], errors="coerce")
df = df.dropna(subset=["订单号", "退款金额"])

result = df.groupby("商户号", as_index=False)["退款金额"].sum()
print(result.head())

这里有个经验,errors="coerce" 很实用。先把脏值打成空,再统一筛,比你写一堆 try/except 清爽。

4. openpyxl:最后一公里,还是得回到 Excel

很多工具前面用 pandas 算完,最后还得给业务一个“能看、能筛、能标红”的表。这个时候 openpyxl 比纯导出 csv 更像人话。

from openpyxl import load_workbook
from openpyxl.styles import PatternFill

wb = load_workbook("处理结果.xlsx")
ws = wb.active
red = PatternFill("solid", fgColor="FFCCCC")

for row in range(2, ws.max_row + 1):
if ws[f"F{row}"].value == "失败":
        ws[f"F{row}"].fill = red

wb.save("处理结果_标记版.xlsx")

内部工具不是只跑通就完了,结果文件能不能直接发群里,也是生产力。

5. httpx:调内部接口,比 requests 更顺手

我现在写内部工具,更愿意直接上 httpx。同步异步都能玩,超时、连接池这些也更顺。

import httpx

defquery_order(order_no: str):
with httpx.Client(timeout=5.0) as client:
        resp = client.get(
"http://order-service/api/order/detail",
            params={"orderNo": order_no},
            headers={"X-Token": "internal-token"}
        )
        resp.raise_for_status()
return resp.json()

这种地方我第一眼先加 timeout,不加基本等着被坑。内部服务一慢,脚本就跟死了一样。

6. tenacity:重试别自己乱写

重试这东西,看着简单,写着最容易恶心。尤其是调用 OA、ERP、老系统接口,偶发超时很常见。自己写 while true,后面大概率忘了退避、忘了兜底。

from tenacity import retry, stop_after_attempt, wait_fixed

@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
defpush_notice(payload: dict):
with httpx.Client(timeout=3.0) as client:
        r = client.post("http://notify-service/send", json=payload)
        r.raise_for_status()
return r.json()

这里别滥用。幂等接口可以重试,扣款、发券这种动作,先想清楚再下手。

7. loguru:日志别再 print 一路了

内部工具一开始大家都喜欢 print,等出问题了,才发现没时间、没文件、没上下文,根本没法翻。

from loguru import logger

logger.add("tool.log", rotation="10 MB", retention="7 days")

logger.info("开始处理退款单")
logger.error("订单 {} 查询失败", "A20260318001")

日志这东西,平时嫌多,出事时嫌少。尤其批量处理脚本,没有日志,复盘基本靠猜。

这 7 个库凑一起,已经能覆盖公司里大部分内部工具场景了:命令行入口、参数校验、表格处理、Excel 回写、接口调用、失败重试、日志留痕。真要我选一套“拿来就干”的组合,大概率就是这几个。