第6讲、 Odoo 18 `tools` 模块深度分析
Odoo 18 中的 odoo/tools
目录是核心工具模块的集合,封装了大量通用功能,包括数据处理、安全校验、缓存优化、文件处理、时间转换、国际化、多线程处理等。这些工具模块在整个 Odoo 框架中被频繁引用,是系统高效运行和代码解耦的重要基础。
🧭 目录结构总览
odoo/tools
目录下包含了众多核心文件,以下是常见模块及其主要功能:
odoo/tools/
├── __init__.py
├── cache.py # 缓存机制
├── config.py # 配置解析器(封装 argparse)
├── convert.py # XML/CSV 转换(用于加载数据)
├── date_utils.py # 日期操作辅助
├── float_utils.py # 浮点数精度处理
├── image.py # 图像处理工具
├── misc.py # 杂项工具函数
├── profiler.py # 性能分析
├── safe_eval.py # 安全的表达式计算
├── translate.py # 翻译与 i18n 支持
├── unique.py # 唯一 ID 生成器
├── view_validation.py # XML 视图结构校验
├── yaml_import.py # YAML 数据导入支持
├── threading.py # 多线程扩展支持
└── ... (其他工具模块)
此外,tools
目录还包含大量辅助模块,涵盖路径定位、条码、邮件、国际化、SQL、性能分析、版本兼容等各类场景。例如:
appdirs.py
:跨平台应用目录定位barcode.py
:条码校验与生成cloc.py
:代码行数统计func.py
:函数式工具i18n.py
:国际化辅助json.py
:JSON 序列化/反序列化mail.py
:邮件相关工具osutil.py
:操作系统相关工具profiler.py
:性能分析set_expression.py
:集合表达式解析sql.py
:SQL 辅助template_inheritance.py
:QWeb 模板继承xml_utils.py
:XML 处理工具- …(详见源码)
🔍 核心模块源码解读
1. cache.py
:高效缓存机制
-
功能:实现内存级缓存,广泛用于 ORM 与 API 层,提升性能(如
@ormcache
,@lru
等)。 -
核心类与装饰器:
Cache
:缓存对象基础类LRU
:最近最少使用缓存- 装饰器:
@ormcache
,@lru
,@lazy_property
-
示例:
from odoo.tools.cache import ormcacheclass Product(models.Model):_name = "product.product"@ormcache('self.env.uid', 'self.env.cr.dbname')def compute_heavy_data(self):# 缓存计算结果,避免重复开销...
-
进阶:支持 context 参与缓存 key(
@ormcache_context
),可统计命中率,支持全局清理。
2. safe_eval.py
:安全表达式求值
-
功能:封装
eval()
,只允许白名单表达式,广泛用于配置、域表达式、动态代码等。 -
安全设计:
- 屏蔽所有内置函数,仅开放部分安全函数
- 支持自定义上下文环境
- 严格校验 Python 字节码,禁止导入、属性访问、全局变量等
-
示例:
from odoo.tools.safe_eval import safe_evalsafe_eval("1 + 2") # ✅ 合法 safe_eval("__import__('os')") # ❌ 拦截
3. convert.py
:数据文件加载器
- 功能:解析 XML、CSV、YAML 文件并转换为数据库记录。模块安装时的数据导入均通过此模块处理。
- 主要类与函数:
convert_xml_import()
convert_csv_import()
- 机制:
- 解析 Odoo 的 XML 模型结构
- 支持
External ID
跨模块引用 - 支持
noupdate
,eval
,ref
等语法
4. float_utils.py
:浮点数精度处理
-
功能:专门处理金额、精度、舍入误差等问题,避免 IEEE-754 浮点误差。
-
常用函数:
float_compare
float_round
float_is_zero
-
示例:
from odoo.tools.float_utils import float_comparefloat_compare(0.1 + 0.2, 0.3, precision_digits=2) # ✅ 避免误差问题
5. config.py
:配置参数解析
-
功能:封装对
odoo.conf
配置文件和命令行参数的读取,主要用于服务启动时的配置加载。 -
示例:
from odoo.tools.config import configdb_host = config['db_host'] addons_path = config['addons_path']
6. translate.py
:翻译系统
- 功能:负责
.po
文件的加载、翻译字典生成、多语言处理等,支持导入导出翻译、多语言视图/字段、_()
方法文本翻译。
7. view_validation.py
:视图 XML 校验
- 功能:检查模块视图定义中的 XML 是否符合语法要求,如标签嵌套、字段合法性、继承关系等。
8. misc.py
:杂项工具集合
- 功能:包含大量通用函数,如
file_open
(安全文件访问)、apply_instructions
(字段计算表达式)、uniq_list
(去重列表)、split_every
(分块处理)等。 - 适用场景:文件、字符串、集合、国际化、加密、排序、分组、异常处理等底层通用需求。
9. threading.py
:Odoo 特化的线程工具
- 功能:封装标准
threading
,支持线程本地数据、线程安全的env
调度等。
10. image.py
:图像处理工具
- 功能:对 PIL(Pillow)进行封装,支持图片缩放、格式转换、中心裁剪、二进制图片处理等。
🧩 多工具协作实战示例
在模型中导入数据并缓存计算结果:
from odoo import models, fields, api
from odoo.tools.cache import ormcache
from odoo.tools.safe_eval import safe_eval
from odoo.tools.float_utils import float_roundclass MyModel(models.Model):_name = 'my.model'price = fields.Float()@ormcache('self.id')def compute_taxed_price(self):return float_round(self.price * 1.13, precision_digits=2)def run_custom_eval(self, expr):return safe_eval(expr, {'price': self.price})
✅ 总结与对比
模块名 | 主要作用 | 应用示例 |
---|---|---|
cache.py | LRU 缓存、ORM 缓存 | 加速计算字段、视图加载 |
safe_eval.py | 安全计算表达式 | 动态域、公式字段 |
convert.py | XML/CSV 数据导入 | 安装模块数据初始化 |
float_utils.py | 浮点数比较、四舍五入 | 金额字段处理 |
translate.py | 翻译与多语言支持 | 字段翻译、视图翻译 |
config.py | 读取配置文件和参数 | 启动服务、获取配置项 |
view_validation | XML 视图语法校验 | 提前发现视图定义错误 |
misc.py | 通用函数集合 | 文件处理、结构操作 |
image.py | 图像二进制处理 | 用户头像、图标裁剪 |
其他(appdirs等) | 路径、邮件、国际化等辅助 | 各类底层通用场景 |
🛠️ 更多工具模块与进阶用法
除了上述主力模块,odoo/tools
目录还包含大量实用的辅助工具,覆盖路径定位、条码、邮件、国际化、SQL、性能分析、版本兼容等各类场景。常见的还有:
appdirs.py
、barcode.py
、cloc.py
、func.py
、i18n.py
、json.py
、mail.py
、osutil.py
、profiler.py
、set_expression.py
、sql.py
、template_inheritance.py
、xml_utils.py
等。
具体可参考源码,每个模块头部和函数都有详细注释。
🔬 进阶用法与实战技巧
- 缓存高级用法:
@ormcache_context
支持 context 变量参与缓存 key,log_ormcache_stats()
可输出缓存命中率,支持全局清理。 - 安全表达式执行:
safe_eval
对 Python 字节码严格白名单校验,支持自定义上下文,适用于 domain、公式字段、动态规则等。 - 浮点数精度处理:
float_round
、float_is_zero
、float_repr
等专门处理 IEEE-754 浮点误差,推荐所有金额、数量等精度敏感场景都用 float_utils。 - 数据导入与批量初始化:
convert.py
支持 XML/CSV/YAML 批量导入,支持<record>
,<function>
,<menuitem>
等标签,idref
、noupdate
、eval
等机制支持跨模块引用和条件导入。 - 杂项工具箱:
misc.py
提供file_open
(安全文件访问)、split_every
(分块处理)、unique
(去重)、formatLang
(本地化格式化)、get_lang
(多语言环境)等,适合各类底层场景。
💡 典型代码片段
# 使用 misc.py 的 file_open 读取模块内文件
from odoo.tools.misc import file_open
with file_open('my_module/static/description/icon.png', 'rb') as f:data = f.read()# 使用 float_utils 进行金额精度处理
from odoo.tools.float_utils import float_round
rounded = float_round(123.456, precision_digits=2) # 123.46# 使用 safe_eval 安全执行用户表达式
from odoo.tools.safe_eval import safe_eval
result = safe_eval('price * 1.13', {'price': 100}) # 113.0
🧬 源码深度解读
1. sql.py
:安全与组合式的 SQL 构建器
Odoo 的 tools.sql
提供了安全、可组合的 SQL 语句包装器 SQL
类,极大简化了动态 SQL 的拼接与参数传递,核心特性如下:
- SQL 对象封装:
SQL
类将 SQL 语句和参数分离,支持嵌套组合,避免手动拼接字符串带来的 SQL 注入风险。 - 参数化与安全:支持
%s
占位符和命名参数,所有参数都通过 psycopg2 传递,自动防注入。 - 组合式 API:SQL 片段可以嵌套组合,
SQL("%s = %s", SQL.identifier(col), val)
,最终统一输出 code 和 params。 - 辅助函数丰富:如
create_index
、drop_view_if_exists
、index_exists
、make_identifier
等,封装了常用的表结构变更、索引管理等操作。 - 元数据追踪:
to_flush
属性可追踪 SQL 依赖的字段,便于后续缓存失效等场景。
实用建议:自定义底层 SQL 操作时,优先用 SQL
类和相关工具函数,既安全又易维护。
2. lru.py
:线程安全的 O(1) LRU 缓存
Odoo 的 tools.lru.LRU
是一个基于 OrderedDict
的线程安全 LRU(最近最少使用)缓存实现,特点如下:
- O(1) 操作:所有 get/set/del 操作均为常数时间复杂度。
- 线程安全:所有方法都加锁(
@locked
装饰器),可在多线程环境下安全使用。 - 自动淘汰:超出容量自动淘汰最久未使用的元素。
- API 兼容字典:实现了
MutableMapping
,可像普通字典一样用。 - 用法场景:被 ORM 缓存、视图缓存等高频场景广泛调用。
3. cache.py
:ORM 缓存装饰器与统计
Odoo 的 tools.cache
是 ORM 层性能优化的核心,提供了 @ormcache
、@ormcache_context
等装饰器,底层依赖 LRU 实现。主要机制:
- @ormcache 装饰器:为模型方法提供参数化缓存,缓存 key 可灵活指定(如
@ormcache('self.env.uid', 'self.env.cr.dbname')
)。 - @ormcache_context:支持 context 变量参与缓存 key,适合多租户/多语言等场景。
- 缓存统计:
ormcache_counter
统计命中/未命中/错误/耗时,log_ormcache_stats()
可输出全局缓存命中率。 - 缓存清理:通过
model.pool.clear_all_caches()
或registry.clear_cache()
清理所有缓存。 - 兼容性与安全:装饰器自动处理参数、兼容老用法,且不允许缓存 Recordset(避免游标失效)。
4. mail.py
:邮件与 HTML 处理工具箱
Odoo 的 tools.mail
是邮件和富文本处理的"瑞士军刀",涵盖邮件地址解析、HTML 清洗、内容格式化等,主要亮点:
- 邮件地址处理:
email_normalize
、email_split
、email_domain_extract
等,支持国际化、去重、批量处理。 - HTML 安全清洗:
html_sanitize
、html_normalize
、html2plaintext
,基于 lxml,支持自定义白名单、样式过滤、条件注释保留等。 - 富文本与纯文本互转:
plaintext2html
、html2plaintext
,适合邮件正文、通知等场景。 - 邮件追踪与格式化:如
generate_tracking_message_id
、formataddr
、encapsulate_email
,支持邮件头生成、地址封装等。 - 健壮性与兼容性:对各类邮件客户端、特殊 HTML 标签、国际化邮箱等做了大量兼容处理。
📚 参考与源码
更多细节可参考 Odoo 源码的 odoo/tools
目录,每个模块头部和函数都有详细注释。