本节摘要:环境化学用来判断污染物的通用工具,可归结为四把尺子:热力学告诉你“能否自发”,动力学告诉你“多久能变”,酸碱平衡告诉你“平衡态在哪个 pH”,氧化还原告诉你“电子往哪跑”;再加上计量这把总秤,把一切换算成摩尔与质量。本节演示这四把尺子如何用几行可运行的 Python 从监测数据里反推机理,并给出反应方向和反应速率的量化判据。
阅读完本节,你应当能够:
拿到一份水质报告,会先冒出三个问题:这个反应会不会发生?要多长时间才达平衡?上次测到 5,这次测到 4.5,是正常波动还是趋势?这三问恰好分别对应动力学、热力学与计量。本节不堆公式,而是演示怎么把这三问用代码回答掉。
污染物是否会被氧化成毒性更小的形态,首先看反应的自发性。用吉布斯自由能判据:当自由能变小于零时反应自发。对恒温下的反应,需要同时考虑标准项和浓度项:
import math # 以 Cr 六价还原为三价为例,判断给定条件下是否自发 # 反应: Cr2O7(2-)+14H(+)+6e -> 2Cr(3+)+7H2O, E0较正 R, T, F = 8.314, 298.15, 96485.0 n = 6 # 转移电子数 E0 = 1.33 # 标准电极电位 V pH = 5.0 # 工程条件下水体 pH # 用能斯特方程算该 pH 下的实际电位 E = E0 - 0.0592 / n * 14 * pH G = -n * F * E # 吉布斯自由能 J/mol print(f"实际电位 E = {E:.3f} V") print(f"吉布斯自由能变 = {G/1000:.1f} kJ/mol(负则自发)") order = "可自发被还原" if G < 0 else "稳定存在" print("铬在此酸性水中:", order)
输出会告诉我们:强酸性高氧化性条件下,六价铬热力学上倾向于还原成三价铬。而一旦水体偏中性、还原剂不足,这个反应就慢下来甚至停滞——这正解释了为何同一条河不同断面的铬形态差异巨大。热力学决定“能不能”,但它不回答“快不快”,这正是下一把尺子的用武之地。
很多污染物在环境中的衰减符合一级动力学,即单位时间消失的比例恒定。农药在土壤中的降解、苯系物在地表水中的光解,大多如此。半衰期是环境化学最常用的“寿命”指标:
# 一级动力学衰减与半衰期 import math def half_life(k): return math.log(2) / k def left(c0, k, t): return c0 * math.exp(-k * t) k1 = 0.0462 # 日^-1,来自实验室测定的某农药降解速率 c0 = 120.0 # 初始检出 μg/L t10 = half_life(k1) c10 = left(c0, k1, 10) print(f"该农药半衰期约 {t10:.1f} 天") print(f"10 天后剩余浓度 {c10:.1f} 微克每升") # 不同温度下 k 变化对残留影响 k_hot = 0.115 c10_hot = left(c0, k_hot, 10) print(f"夏季升温后 10 天仅剩 {c10_hot:.1f} 微克每升")
同一个量级,冬季可能几个月没感觉,夏季却明显消退——这解释了为什么同样污染浓度,季节不同、风险不同。动力学给“监测反推”提供时间维度:测得某个残留浓度,就能倒推出大概从何时起要开始外排。
酸碱与氧化还原并不独立。水的碱度会影响重金属电位,进而改变其形态与迁移。下面把 pH 计算与能斯特联起来,看一个“低 pH 让溶解态重金属活化”的典型过程:
# 弱酸的 pH 近似计算: 醋酸作为模型污染物 Kw = 1e-14 Ka = 1.8e-5 # 醋酸 C = 0.001 # 0.001 mol/L # 一水酸近似: x=sqrt(Ka*C) import math x = math.sqrt(Ka * C) H = math.sqrt(Ka * C + Kw) pH = -math.log10(H) print(f"0.001 mol/L 醋酸溶液 pH ≈ {pH:.2f}") # 不同酸度下重金属氢氧化物溶解性(量级示意) for pH_val in [3.0, 5.0, 6.5]: log_h = 2 * pH_val # 简化示意,真实需溶度积 print(f"pH={pH_val} 时游离金属量级 log(浓度)≈{log_h:.1f}")
关键在于:pH 每降一单位,某些形态的溶解度会数量级上升。田地酸化后,原本被土壤固定的镉又重新溶出、被作物吸收,就是这个机制。读数 pH 5 与 pH 6.5 之间,看似差距不大,对毒物迁移的影响却是数量级。
最后也是最朴素的一步:把 mol 和 mg 对齐,因为报告单上写的是 mg/L,而反应式里算的是摩尔。这种换算错误在环境应急中最常见、也最致命。
# 摩尔与质量浓度换算 MW_lead = 207.2 # 铅 g/mol conc_mgL = 0.025 # 检出 Pb mg/L mol_conc = conc_mgL / 1000 / MW_lead print(f"0.025 mg/L 铅 = {mol_conc:.3e} mol/L") # 连接流量算摩尔通量 flow = 2.0 mol_flux = mol_conc * flow print(f"每秒摩尔通量 {mol_flux:.2e} mol") # 若换算少除 1000,会高估 1000 倍——应急里会因浓度被错误高估而误判 wrong = conc_mgL / MW_lead print(f"错误换算得到 {wrong:.3e},差点差千倍")
上面这段可视化了一个让你吓一跳的陷阱:mg 与 g 只差一个 1000,却足以让应急响应的级别判断从“可忽略”跳到“紧急”。环境化学里所有高级模型,都建立在这把总秤上。
某水厂在线仪表检测到出厂水某参数异常偏高,值班人员未做单位核对便上报“重度超标”,触发限水。事后复核发现,仪表输出单位为毫克每升,而被误读成微克每升换算上报,实际浓度远低于限值。事件本身变动不大,但暴露出:环境化学的“计量尺子”若失准,最先失的是决策的信心。这也是本书把计量单独拿出来反复强调的原因。
把四把尺子按顺序串起来:

先判断“能否”,再估算“多久”,再定“在哪”,最后统一“计量”,四步构成反推机理的完整流水线。