uuid4()是最常用且适合分布式场景的选择,它不依赖系统时间或硬件信息,纯随机生成,冲突概率极低(约1/2¹²²);uuid1()存在隐私泄露和时钟回拨风险,uuid3()/uuid5()为确定性哈希,相同输入必得相同输出,无法满足每次调用生成新唯一值的需求。

uuid4() 是最常用且适合分布式场景的选择,它不依赖系统时间或硬件信息,纯随机生成,冲突概率极低(约 1/2¹²²)。
为什么不用 uuid1() 或 uuid3()/uuid5()?
uuid1() 基于时间戳 + MAC 地址,存在隐私泄露风险(暴露网卡地址)和时钟回拨导致重复的可能;uuid3() 和 uuid5() 是确定性哈希(分别用 MD5/SHA1),输入相同则输出相同,无法满足“每次调用都唯一”的需求。分布式环境下,你无法保证所有节点输入一致且不冲突,所以它们不适合“生成唯一 ID”这个目标。
-
uuid1()在容器或云环境常因 MAC 地址为 00:00:00:00:00:00 而退化为纯时间戳,重复风险上升 -
uuid3("foo")和uuid5("foo")每次运行结果固定,不能用于生成新 ID - 真正需要“每次调用都产生新唯一值”的场景,只有
uuid4()和自定义随机方案可选
直接用 uuid.uuid4() 就够了吗?
够,但要注意默认返回的是 UUID 对象,不是字符串。很多数据库、API 或日志系统要求字符串格式,漏掉 str() 转换会导致 TypeError 或意外序列化行为。
import uuid uid = uuid.uuid4() # <class> print(uid) # 9f6e8c1a-2b3c-4d5e-6f7a-8b9c0d1e2f3a(打印时自动转 str) print(type(uid)) # <class> print(uid.hex) # 9f6e8c1a2b3c4d5e6f7a8b9c0d1e2f3a(无连字符,32 字符) print(str(uid)) # "9f6e8c1a-2b3c-4d5e-6f7a-8b9c0d1e2f3a"(标准 36 字符格式)</class></class>
- 存入 PostgreSQL 的
UUID字段:直接传uid(对象)即可,驱动会处理 - 写入 JSON 或发 HTTP 请求:必须用
str(uid),否则json.dumps()报错 - 想省存储空间(如 Redis key):可用
uid.hex,但注意丢失可读性与标准兼容性
性能和并发安全有隐患吗?
没有。Python 的 uuid4() 底层调用 os.urandom()(Linux/macOS)或 CryptGenRandom(Windows),是操作系统级加密安全随机源,线程安全,无需加锁。每秒生成数万 UUID 完全无压力。
- 不要用
random.uuid4()——random模块不安全,且没有uuid4方法 - 避免自己拼接时间戳 + 随机数:既没
uuid4()简洁,又容易引入偏差或重复逻辑 - 在异步环境中(如 asyncio)同样安全,
uuid4()不含任何阻塞 I/O
真正要留心的只有一件事:别把 uuid.uuid4() 的结果缓存复用——它本意就是每次调用都生成新值,复用就失去唯一性意义了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











