第16讲、Odoo 18 序号(Sequence)详解

article/2025/7/13 16:47:25

目录

  1. 序号系统概述
  2. 底层实现原理
  3. 常见序号规则
  4. 使用方法与最佳实践
  5. 案例分析:客户工单管理系统
  6. 常见问题与解决方案
  7. 总结

序号系统概述

Odoo 中的序号(Sequence)系统是一个用于生成唯一标识符的核心机制,主要用于为业务单据(如销售订单、采购订单、发票等)自动分配编号。序号系统由 ir.sequence 模型实现,它提供了一种事务安全(transaction-safe)的方式来生成这些唯一标识符。

序号系统的主要特点:

  • 唯一性:确保生成的编号在特定范围内唯一
  • 格式灵活:支持前缀、后缀、填充等多种格式化选项
  • 日期智能:支持基于日期的动态占位符
  • 并发安全:在高并发环境下保证序号不重复
  • 按日期范围重置:支持按年度、月度等周期重置序号

底层实现原理

1. 数据库实现机制

Odoo 18 的序号系统提供了两种实现方式:

1.1 标准实现(Standard)
  • 底层机制:利用 PostgreSQL 的序列(Sequence)功能
  • 实现方式
    • 创建时,通过 _create_sequence 函数在 PostgreSQL 中创建一个序列
    • 序列名称格式为 ir_sequence_XXX(XXX 为序号记录的 ID,补零至 3 位)
    • 使用 PostgreSQL 的 nextval() 函数获取下一个值
  • 特点
    • 性能高效
    • 允许序号间有间隙(如删除记录后)
    • 并发安全

源码实现:

def _next_do(self):if self.implementation == 'standard':number_next = _select_nextval(self._cr, 'ir_sequence_%03d' % self.id)else:number_next = _update_nogap(self, self.number_increment)return self.get_next_char(number_next)
1.2 无间隙实现(No Gap)
  • 底层机制:通过数据库行锁(row-level lock)确保序号连续
  • 实现方式
    • 使用 SELECT ... FOR UPDATE NOWAIT 锁定记录
    • 读取当前 number_next
    • 更新 number_next 为当前值加上增量
  • 特点
    • 确保序号连续,不会有间隙
    • 性能相对较低(需要锁定)
    • 适用于财务等要求序号严格连续的场景

源码实现:

def _update_nogap(self, number_increment):self.flush_recordset(['number_next'])number_next = self.number_nextself._cr.execute("SELECT number_next FROM %s WHERE id=%%s FOR UPDATE NOWAIT" % self._table, [self.id])self._cr.execute("UPDATE %s SET number_next=number_next+%%s WHERE id=%%s " % self._table, (number_increment, self.id))self.invalidate_recordset(['number_next'])return number_next

2. 日期范围子序列机制

Odoo 18 支持按日期范围使用不同的子序列,通常用于按年度或月度重置序号:

  • 实现模型ir.sequence.date_range
  • 工作原理
    • use_date_range 设置为 True 时启用
    • 系统会根据当前日期查找匹配的日期范围记录
    • 如果找不到匹配的日期范围,会自动创建一个新的(通常按年度)
    • 每个日期范围有自己的序号计数器

源码实现:

def _next(self, sequence_date=None):""" Returns the next number in the preferred sequence in all the ones given in self."""if not self.use_date_range:return self._next_do()# date modedt = sequence_date or self._context.get('ir_sequence_date', fields.Date.today())seq_date = self.env['ir.sequence.date_range'].search([('sequence_id', '=', self.id), ('date_from', '<=', dt), ('date_to', '>=', dt)], limit=1)if not seq_date:seq_date = self._create_date_range_seq(dt)return seq_date.with_context(ir_sequence_date_range=seq_date.date_from)._next()

3. 前缀和后缀插值机制

Odoo 序号系统支持在前缀和后缀中使用动态占位符,通过字符串插值实现:

  • 插值字典:包含日期相关的各种格式化值
  • 支持的占位符
    • %(year)s - 年份(4位)
    • %(month)s - 月份(2位)
    • %(day)s - 日期(2位)
    • %(y)s - 年份(2位)
    • %(doy)s - 一年中的第几天
    • %(woy)s - 一年中的第几周
    • %(weekday)s - 星期几
    • %(h24)s - 小时(24小时制)
    • %(h12)s - 小时(12小时制)
    • %(min)s - 分钟
    • %(sec)s - 秒

源码实现:

def _interpolation_dict(self):now = range_date = effective_date = datetime.now(pytz.timezone(self._context.get('tz') or 'UTC'))if date or self._context.get('ir_sequence_date'):effective_date = fields.Datetime.from_string(date or self._context.get('ir_sequence_date'))if date_range or self._context.get('ir_sequence_date_range'):range_date = fields.Datetime.from_string(date_range or self._context.get('ir_sequence_date_range'))sequences = {'year': '%Y', 'month': '%m', 'day': '%d', 'y': '%y', 'doy': '%j', 'woy': '%W','weekday': '%w', 'h24': '%H', 'h12': '%I', 'min': '%M', 'sec': '%S'}res = {}for key, format in sequences.items():res[key] = effective_date.strftime(format)res['range_' + key] = range_date.strftime(format)res['current_' + key] = now.strftime(format)return res

4. 数字格式化机制

序号的数字部分可以通过 padding 参数控制格式:

  • 实现方式:使用 Python 的字符串格式化
  • 格式化规则'%%0%sd' % self.padding % number_next
  • 示例
    • 如果 padding=4number_next=1,则格式化为 0001
    • 如果 padding=6number_next=42,则格式化为 000042

源码实现:

def get_next_char(self, number_next):interpolated_prefix, interpolated_suffix = self._get_prefix_suffix()return interpolated_prefix + '%%0%sd' % self.padding % number_next + interpolated_suffix

常见序号规则

1. 基本序号规则

规则类型示例说明
简单数字0001, 0002, ...仅使用数字,通过 padding 控制前导零
前缀固定SO0001, SO0002, ...使用固定前缀 + 数字
后缀固定0001/A, 0002/A, ...使用数字 + 固定后缀
前后缀SO0001/A, SO0002/A, ...使用固定前缀 + 数字 + 固定后缀

2. 日期相关序号规则

规则类型示例配置
年份前缀2025/0001, 2025/0002, ...prefix='%(year)s/'
年月前缀2025-01/0001, 2025-01/0002, ...prefix='%(year)s-%(month)s/'
年份后缀0001/2025, 0002/2025, ...suffix='/%(year)s'
年月日完整20250101-0001, 20250101-0002, ...prefix='%(year)s%(month)s%(day)s-'

3. 公司或部门相关序号规则

规则类型示例实现方式
公司代码前缀COMP1-0001, COMP1-0002, ...在前缀中硬编码公司代码或使用上下文变量
部门代码前缀HR-0001, FIN-0002, ...在前缀中硬编码部门代码或使用上下文变量

4. 混合序号规则

规则类型示例配置
年份+类型SO/2025/0001, PO/2025/0002, ...在模型中定义不同序列,前缀包含业务类型和年份
公司+年份+类型COMP1/SO/2025/0001, ...结合公司代码、业务类型和年份的复杂前缀
年度重置序号每年从 0001 开始启用 use_date_range=True 并按年创建日期范围

5. 特殊序号规则

规则类型说明实现方式
严格连续序号确保序号无间隙,适用于财务凭证等使用 implementation='no_gap'
多序列组合在一个编号中组合多个序列的值在代码中调用多个序列并组合结果
条件序号根据记录属性选择不同序列在代码中根据条件选择不同的序列代码

在这里插入图片描述


使用方法与最佳实践

1. 通过代码调用序号

1.1 基本调用方式
# 通过代码获取序号
next_number = self.env['ir.sequence'].next_by_code('my.sequence.code')# 带日期参数的调用(用于指定日期的序号)
specific_date = fields.Date.from_string('2025-01-15')
next_number = self.env['ir.sequence'].next_by_code('my.sequence.code', sequence_date=specific_date)
1.2 在模型创建时自动分配序号
@api.model
def create(self, vals):if not vals.get('name') or vals['name'] == '/':vals['name'] = self.env['ir.sequence'].next_by_code('my.model') or '/'return super(MyModel, self).create(vals)

2. 通过XML配置序号

2.1 基本序号配置
<record id="seq_my_model" model="ir.sequence"><field name="name">My Model Sequence</field><field name="code">my.model</field><field name="prefix">MY/%(year)s/</field><field name="padding">4</field><field name="number_next">1</field><field name="number_increment">1</field>
</record>
2.2 带日期范围的序号配置
<record id="seq_my_model_with_range" model="ir.sequence"><field name="name">My Model Sequence (Yearly)</field><field name="code">my.model.yearly</field><field name="prefix">MY/%(range_year)s/</field><field name="padding">4</field><field name="number_next">1</field><field name="use_date_range">True</field>
</record>

3. 序号的高级用法

3.1 公司特定序号
# 获取当前公司的序号
company_id = self.env.company.id
seq_ids = self.env['ir.sequence'].search([('code', '=', 'my.sequence.code'),('company_id', 'in', [company_id, False])
], order='company_id')
if seq_ids:next_number = seq_ids[0].next_by_id()
3.2 序号预测(不消耗)
# 预测下一个序号值但不实际消耗它
seq_id = self.env['ir.sequence'].search([('code', '=', 'my.sequence.code')], limit=1)
if seq_id:predicted_value = seq_id._get_number_next_actual()
3.3 自定义上下文变量
# 使用自定义上下文变量
custom_context = {'ir_sequence_date': '2025-06-01',  # 指定日期
}
next_number = self.env['ir.sequence'].with_context(custom_context).next_by_code('my.sequence.code')

案例分析:客户工单管理系统

业务需求

创建一个客户工单管理系统,要求:

  1. 工单编号格式:[部门代码]/[年份]/[流水号]-[优先级]
    • 例如:SUP/2025/0001-H(支持部门2025年第1号高优先级工单)
  2. 每年重置流水号
  3. 不同部门使用不同前缀:
    • 支持部门(Support):SUP
    • 技术部门(Technical):TEC
    • 销售部门(Sales):SAL
  4. 工单优先级标识:
    • 高(High):H
    • 中(Medium):M
    • 低(Low):L

实现方案

1. 序列配置

为三个不同部门创建三个不同的序列:

<!-- 支持部门工单序列 -->
<record id="seq_customer_ticket_support" model="ir.sequence"><field name="name">Customer Ticket (Support)</field><field name="code">customer.ticket.support</field><field name="prefix">SUP/%(range_year)s/</field><field name="padding">4</field><field name="number_next">1</field><field name="number_increment">1</field><field name="use_date_range">True</field><field name="implementation">standard</field><field name="company_id" eval="False"/>
</record><!-- 技术部门工单序列 -->
<record id="seq_customer_ticket_technical" model="ir.sequence"><field name="name">Customer Ticket (Technical)</field><field name="code">customer.ticket.technical</field><field name="prefix">TEC/%(range_year)s/</field><field name="padding">4</field><field name="number_next">1</field><field name="number_increment">1</field><field name="use_date_range">True</field><field name="implementation">standard</field><field name="company_id" eval="False"/>
</record><!-- 销售部门工单序列 -->
<record id="seq_customer_ticket_sales" model="ir.sequence"><field name="name">Customer Ticket (Sales)</field><field name="code">customer.ticket.sales</field><field name="prefix">SAL/%(range_year)s/</field><field name="padding">4</field><field name="number_next">1</field><field name="number_increment">1</field><field name="use_date_range">True</field><field name="implementation">standard</field><field name="company_id" eval="False"/>
</record>
2. 模型实现
class CustomerTicket(models.Model):_name = 'customer.ticket'_description = 'Customer Support Ticket'name = fields.Char(string='Ticket Number', required=True, copy=False, readonly=True, default='/')partner_id = fields.Many2one('res.partner', string='Customer', required=True)department = fields.Selection([('support', 'Support'),('technical', 'Technical'),('sales', 'Sales')], string='Department', required=True)priority = fields.Selection([('low', 'Low'),('medium', 'Medium'),('high', 'High')], string='Priority', default='medium', required=True)description = fields.Text(string='Description')date_created = fields.Date(string='Creation Date', default=fields.Date.today)state = fields.Selection([('draft', 'Draft'),('open', 'Open'),('in_progress', 'In Progress'),('done', 'Done'),('cancelled', 'Cancelled')], string='Status', default='draft')@api.modeldef create(self, vals):"""重写创建方法,自动分配工单编号"""if vals.get('name', '/') == '/':# 根据部门选择不同的序列代码department = vals.get('department')priority = vals.get('priority', 'medium')# 获取部门对应的序列代码seq_code = 'customer.ticket.support'  # 默认支持部门if department == 'technical':seq_code = 'customer.ticket.technical'elif department == 'sales':seq_code = 'customer.ticket.sales'# 获取序列号ticket_number = self.env['ir.sequence'].next_by_code(seq_code)# 添加优先级后缀priority_suffix = 'M'  # 默认中优先级if priority == 'high':priority_suffix = 'H'elif priority == 'low':priority_suffix = 'L'# 组合完整工单编号vals['name'] = f"{ticket_number}-{priority_suffix}"return super(CustomerTicket, self).create(vals)

实现分析

  1. 序列配置特点

    • 使用 use_date_range=True 实现按年度重置
    • 使用 %(range_year)s 在前缀中包含年份
    • 设置 padding=4 确保序号至少有 4 位,不足补零
  2. 序号生成流程

    • 根据工单的 department 字段选择对应的序列代码
    • 使用 next_by_code 获取基本序号
    • 根据 priority 字段添加后缀
    • 组合成最终格式:{序列号}-{优先级}
  3. 底层工作原理

    • 模块安装时创建序列记录
    • 对于 standard 实现,创建 PostgreSQL 序列
    • 首次使用时自动创建当年的日期范围记录
    • 每年自动创建新的日期范围记录,实现按年重置

常见问题与解决方案

1. 序号重复问题

问题:在高并发环境下可能出现序号重复

解决方案

  • 使用 no_gap 实现,确保序号唯一性
  • 添加数据库约束,确保 name 字段唯一
_sql_constraints = [('name_unique', 'UNIQUE(name)', 'Ticket number must be unique!')
]

2. 序号格式变更

问题:业务需求变更,需要修改现有序号格式

解决方案

  • 创建新的序列记录,不要修改现有序列
  • 在代码中添加版本判断逻辑,处理新旧格式
# 检查日期判断使用哪种序列格式
today = fields.Date.today()
cutoff_date = fields.Date.from_string('2025-01-01')
if today >= cutoff_date:# 使用新格式序列seq_code = f"customer.ticket.{department}.new"
else:# 使用旧格式序列seq_code = f"customer.ticket.{department}"

3. 序号预览

问题:用户希望在创建记录前预览将要分配的编号

解决方案

  • 添加预览功能,不消耗实际序号
  • 使用 _get_number_next_actual 方法获取当前值但不递增
@api.model
def preview_next_number(self, department):seq_code = f"customer.ticket.{department}"seq = self.env['ir.sequence'].search([('code', '=', seq_code)], limit=1)if not seq:return False# 获取当前值但不递增current_date = fields.Date.today()if seq.use_date_range:date_range = seq.date_range_ids.filtered(lambda r: r.date_from <= current_date <= r.date_to)if not date_range:# 模拟创建日期范围的行为year = fields.Date.from_string(current_date).yeardate_from = f'{year}-01-01'date_to = f'{year}-12-31'next_number = 1else:next_number = date_range.number_next_actualelse:next_number = seq.number_next_actual# 格式化并返回预览return seq._get_next_char(next_number)

4. 多公司环境问题

问题:多公司环境下序号混乱或共享

解决方案

  • 为每个公司创建独立序列
  • 在代码中根据当前公司选择序列
company_id = self.env.company.id
seq_ids = self.env['ir.sequence'].search([('code', '=', seq_code),('company_id', 'in', [company_id, False])
], order='company_id')
if seq_ids:next_number = seq_ids[0].next_by_id()

5. 性能问题

问题:大量序号生成导致性能下降

解决方案

  • 优先使用 standard 实现而非 no_gap
  • 避免频繁调用序号生成
  • 考虑批量预生成序号

总结

Odoo 18 的序号系统提供了一种灵活、强大且事务安全的方式来生成业务单据的唯一标识符。通过合理配置和使用序号系统,可以满足各种业务场景的编号需求,包括:

  1. 多样化的格式:支持前缀、后缀、填充等多种格式化选项
  2. 日期智能:支持基于日期的动态占位符,实现按日期变化的编号
  3. 周期性重置:支持按年度、月度等周期重置序号
  4. 并发安全:在高并发环境下保证序号不重复
  5. 多公司支持:可以为不同公司配置独立序列

通过本文的详细解读和案例分析,相信您已经对 Odoo 18 序号系统有了全面的了解,能够根据业务需求灵活配置和使用序号功能。


http://www.hkcw.cn/article/cMkyKxswqJ.shtml

相关文章

内存管理--《Hello C++ Wrold!》(8)--(C/C++)--深入剖析new和delete的使用和底层实现

文章目录 前言C/C内存分布new和deletenew和delete的底层定位new表达式 内存泄漏作业部分 前言 在C/C编程中&#xff0c;内存管理是理解程序运行机制的核心基础&#xff0c;也是开发高效、稳定程序的关键。无论是局部变量的存储、动态内存的分配&#xff0c;还是对象生命周期的…

Linux之进程间通信

目录 一、进程间通信介绍 1.1、进程间通信目的 1.2、进程间通信发展 1.3、进程间通讯分类 二、管道 三、匿名管道 3.1、示例代码 完整重定向问题&#xff1a; 3.2、⽤ fork 来共享管道原理 3.3、站在⽂件描述符⻆度-深度理解管道 3.4、站在内核⻆度-管道本质 3.5、…

京东轨迹验证码识别代码

一、简介 这个是最新的京东轨迹验证码&#xff0c;需要用户根据轨迹画出对应的曲线。这个和传统的验证码有较大的差异&#xff0c;有非常大的难度。经过长时间的研究&#xff0c;现在终于解决了它的识别问题。 这个是识别效果&#xff0c;和真实轨迹基本上重合&#xff0c;所以…

【Godot】如何导出 Release 版本的安卓项目

在使用 Godot 引擎开发安卓游戏或应用时&#xff0c;发布到应用市场&#xff08;如 Google Play、华为应用市场等&#xff09;通常需要生成一个 Release 版本的 .apk 包&#xff0c;而非 Debug 版本。本文将详细介绍如何将 Godot 项目导出为 Release 版本的安卓项目&#xff0c…

哈喽,我是钓鱼的肝

我嘛&#xff0c;一个五年级的小猴子&#xff0c;哦不&#xff0c;小孩子&#xff0c;给大家看看我长什么样子 呃&#xff0c;放错了 别想了&#xff0c;等你关注我再说 我写博客的缘由就是想让大家一起见证我的进步&#xff0c;二是把我的学习成果让更多人看见&#xff0c;三…

【Linux】网络--网络层--IP协议

个人主页~ 网络--网络层--IP协议 一、基本概念二、IP报头格式三、网络划分四、私有IP和公网IP五、路由路由表 六、与数据链路层之间的协议 一、基本概念 IP 协议是用于在互联网上进行数据传输的一种网络层协议&#xff0c;它为不同网络中的设备提供了一种统一的方式来交换数据…

MCP (模型上下文协议):AI界的“USB-C”标准,开启大模型应用新纪元

今天我们来聊聊一个可能深刻改变 AI 应用开发模式的新技术——MCP (Model Context Protocol&#xff0c;模型上下文协议)。这是由 Anthropic 公司&#xff08;旗下拥有知名大模型 Claude&#xff09;提出的一项旨在统一大模型与外部世界交互方式的“万能接口”。不妨把它想象成…

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术 一、引言 在科学计算和数据分析中&#xff0c;函数与方程的可视化是理解数学关系和物理现象的重要工具。本文基于Python的Tkinter和Matplotlib库&#xff0c;实现一个功能完善的函数与方程可视化工具&#xff…

SpringBoot(六)--- AOP、ThreadLocal

目录 前言 一、AOP基础 1.入门程序 2. AOP核心概念 3. 底层原理 二、AOP进阶 1.通知类型 抽取切入点 2. 切入点表达式 2.1 execution 2.2 annoation 2.3 连接点详解 三、ThreadLocal 前言 AOP&#xff08;面向切面编程&#xff09;&#xff0c;面向切面编程实际就…

贪心算法应用:在线租赁问题详解

贪心算法应用&#xff1a;在线租赁问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;从而希望导致结果是全局最优的算法策略。在线租赁问题(Greedy Algorithm for Online Rentals)是一个经典的贪心算法应用场景&#xff0c;下面我将从多个维度全面…

BA-SAM: 用于 Segment Anything 模型的可扩展偏置模式注意力掩码

概要 在本文中&#xff0c;我们解决了 Segment Anything Model &#xff08;SAM&#xff09; 的图像分辨率变化挑战。SAM 以其零样本泛化性而闻名&#xff0c;当面对具有不同图像大小的数据集时&#xff0c;性能会下降。以前的方法倾向于将图像大小调整为固定大小或采用结构修改…

centos8修改IP地址和Hostname

修改ip地址 vim /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO&#xff1a;设置为 static 表示使用静态 IP 地址。 IPADDR&#xff1a;设置新的 IP 地址。 NETMASK&#xff1a;设置子网掩码。 GATEWAY&#xff1a;设置默认网关&#xff08;可选&#xff0c;但通常需要…

Python Day40 学习(复习学习日志Day5-7)

重新对信贷数据集进行了填补空缺值的操作 自己写的时候&#xff0c;还是出现了问题&#xff1a; 首先是忘记了要定义一下data, 通过data pd.read_csv(data.csv)可以将读取到的数据保存到变量data中&#xff0c;方便后续进行数据分析。 其次&#xff0c;是漏掉了 c data.col…

QML 粒子系统之Affector

目录 基本示例AffectorAge - 改变特定年龄粒子的属性Attractor - 吸引粒子到指定点Friction - 施加摩擦力Gravity - 模拟重力Wander - 随机游走效果Turbulence - 添加湍流效果 下载链接 接上篇QML 粒子系统 (雪花飘落、爆炸粒子效果)&#xff0c;本文继续研究粒子系统中的附属效…

Mac 同时录制系统声音和麦克风声音(OBS + BlackHole 免费版)

&#x1f3ac; 一、你将实现的目标 ✅ 用 OBS 免费录制屏幕时&#xff0c;能同时录到&#xff1a; &#x1f5a5; 系统播放的声音&#xff08;比如视频、PPT音效、背景音乐&#xff09; &#x1f399; 你的麦克风说话声音&#xff08;讲解或旁白&#xff09; &#x1f9f0;…

Pytorch知识点2

Pytorch知识点 1、官方教程2、张量&#x1f9f1; 0、数组概念&#x1f9f1; 1. 创建张量&#x1f4d0; 2. 张量形状与维度&#x1f522; 3. 张量数据类型➗ 4. 张量的数学与逻辑操作&#x1f504; 5. 张量的就地操作&#x1f4e6; 6. 复制张量&#x1f680; 7. 将张量移动到加速…

使用pandas实现合并具有共同列的两个EXCEL表

表1&#xff1a; 表2&#xff1a; 表1和表2&#xff0c;有共同的列“名称”&#xff0c;而且&#xff0c;表1的内容&#xff08;行数&#xff09;<表2的行数。 目的&#xff0c;根据“名称”列的对应内容&#xff0c;将表2列中的“所处行业”填写到表1相应的位置。 实现代…

【农资进销存专用软件】佳易王农资进出库管理系统:赋能农业企业高效数字化管理

一、软件概述与核心优势 &#xff08;一&#xff09;试用版获取方式 资源下载路径&#xff1a;进入博主头像主页第一篇文章末尾&#xff0c;点击卡片按钮&#xff1b;或访问左上角博客主页&#xff0c;通过右侧按钮获取详细资料。 说明&#xff1a;下载文件为压缩包&#xff…

深入理解AMBA总线(七)AHB设计要点和AHB2APB同步桥设计前言

** 深入理解AMBA总线&#xff08;七&#xff09;AHB设计要点和AHB2APB同步桥设计前言 ** 前面的几篇文章介绍了AHB-lite协议。主要内容其实就是文档的介绍加上我自己的一些理解&#xff0c;希望对大家有帮助。今天这篇文章将带来AHB设计需要注意的一些事项&#xff0c;然后带…

消除F/1噪声

目录 简介 如何测量及规定1/f噪声&#xff1f; 1/f噪声对电路有何影响&#xff1f; 如何消除或降低1/f噪声&#xff1f; 简介 本文阐释1/f噪声是什么&#xff0c;以及在精密测量应用中如何降低或消除该噪声。1/f噪声无法被滤除&#xff0c;在精密测量应用中它可能是妨碍实…