Python开发中,大佬们通常会封装哪些功能到工具包(utils)里?

例如

  • 生成一个随机 token
  • 根据字符串生成 hash 值
  • 发送邮件
  • 等较为通用的.

Python开发中,大佬们通常会封装哪些功能到工具包(utils)里?
16 回复

生成 token,hash 和发送邮件功能我都懂,但是"等较为通用的."是啥功能


在Python项目里,我们一般会把那些到处都用得上、但又跟业务逻辑没直接关系的“脏活累活”扔到utils里。说白了,就是让主代码干净点。

最常见的有这几类:

  1. 处理时间的:比如把字符串转成datetime对象,或者算两个日期差多少天。我经常写个parse_date或者get_date_range函数。

    from datetime import datetime, timedelta
    
    def parse_date(date_str, fmt="%Y-%m-%d"):
        """字符串转日期,省得老写try-catch"""
        try:
            return datetime.strptime(date_str, fmt)
        except ValueError as e:
            # 这里可以打个log或者抛个自定义异常
            raise ValueError(f"无法解析日期: {date_str}, 期望格式: {fmt}") from e
    
    def days_ago(days):
        """快速获取几天前的日期"""
        return datetime.now() - timedelta(days=days)
    
  2. 处理字符串和文件的:检查字符串是不是空、安全地读文件、生成随机文件名这些。

    import os
    import uuid
    
    def safe_read(filepath):
        """读文件,自动处理异常和编码"""
        if not os.path.exists(filepath):
            return None
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception:
            return None
    
    def random_filename(original_name):
        """用UUID保留原文件扩展名生成随机文件名"""
        ext = original_name.split('.')[-1] if '.' in original_name else ''
        return f"{uuid.uuid4().hex}.{ext}" if ext else uuid.uuid4().hex
    
  3. 数据转换和校验的:把字典列表转成CSV、验证邮箱格式、深度合并字典(特别是处理配置时)。

    import csv
    from io import StringIO
    
    def dicts_to_csv(data_list):
        """字典列表转CSV字符串"""
        if not data_list:
            return ''
        output = StringIO()
        writer = csv.DictWriter(output, fieldnames=data_list[0].keys())
        writer.writeheader()
        writer.writerows(data_list)
        return output.getvalue()
    
    def merge_dicts(dict1, dict2):
        """递归合并两个字典,dict2优先"""
        result = dict1.copy()
        for key, value in dict2.items():
            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
                result[key] = merge_dicts(result[key], value)
            else:
                result[key] = value
        return result
    
  4. 网络和API相关的:发个简单的HTTP请求、重试逻辑、解析URL参数。

    import requests
    from time import sleep
    
    def fetch_with_retry(url, max_retries=3):
        """带重试的GET请求"""
        for i in range(max_retries):
            try:
                resp = requests.get(url, timeout=5)
                resp.raise_for_status()
                return resp.json()
            except requests.RequestException:
                if i == max_retries - 1:
                    raise
                sleep(2 ** i)  # 指数退避
    
  5. 装饰器和上下文管理器:计时、自动重试、临时改环境变量这些。

    from functools import wraps
    import time
    import os
    
    def timeit(func):
        """打印函数运行时间的装饰器"""
        @wraps(func)
        def wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = func(*args, **kwargs)
            end = time.perf_counter()
            print(f"{func.__name__} 耗时: {end - start:.4f}秒")
            return result
        return wrapper
    
    class change_dir:
        """临时切换工作目录的上下文管理器"""
        def __init__(self, new_path):
            self.new_path = new_path
            self.old_path = None
    
        def __enter__(self):
            self.old_path = os.getcwd()
            os.chdir(self.new_path)
            return self
    
        def __exit__(self, *args):
            os.chdir(self.old_path)
    

总结:工具包就是放那些通用、琐碎、可复用的功能,让主代码更专注业务。

这个比较主观,一般不涉及业务逻辑,又在多处使用,或者比较长的都会抽成 utils

就是省略…

是啊,还有些哪些比较常用的呢?

开关文件
通用清洗数据步骤

其实随意啊

原来要用 utils,我都是放到 function 目录

个人做法:
1. 所有和底层打交道的(读文件, 获取系统时间, etc )
2. 不和业务相关的, 即可以独立出来的, 如 ini 文件解析, 数据清洗
3. 部分数据类

尽量实现
1. 代码复用
2. 不依赖于任何自定义类
3. 便于单元测试

哈哈,开关文件…这么随意么…

function 目录没有体验过,显得好正式

谢谢,3.部分数据类是指保存静态数据的类么

#10
个人习惯而已, 类似于些枚举类之类的

生成随机字符串,生成 md5 之类的吧

比较通用的工具函数

这个比较随意啊

主要还是为了复用

有包用包,没包随手封个函数,也不会再开个文件

函数啊 装饰器 啥的

回到顶部