You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python函数内修改外部变量遇UnboundLocalError的Pythonic解决方法

Python中跟踪余弦相似度最大值的正确解决方法

问题场景

想要跟踪计算得出的余弦相似度分数的当前最大值,但运行代码时持续遇到错误:UnboundLocalError: cannot access local variable 'current_max_cosine_similarity_score' where it is not associated with a value。JavaScript中用let处理函数外部作用域变量无此问题,但Python的作用域规则不同,求符合Python风格的解决办法。

原代码示例:

import math
from functools import reduce

current_max_cosine_similarity_score = -math.inf

def func(acc, v):
  calculated_cosine_similarity_score = ...  # 此处省略计算逻辑

  if calculated_cosine_similarity_score > current_max_cosine_similarity_score:
    current_max_cosine_similarity_score = max([current_max_cosine_similarity_score, calculated_cosine_similarity_score])
    
    acc['cosineSimilarityScore'] = calculated_cosine_similarity_score
  
  return acc


print(reduce(func, [...], {}))

错误原因

Python作用域规则:如果在函数内部对变量执行赋值操作,Python会默认该变量为局部变量,即便外部已定义同名全局变量。代码中current_max_cosine_similarity_score = max(...)属于赋值操作,Python将其判定为局部变量,但if判断时先引用了未赋值的局部变量,因此触发UnboundLocalError。


解决方法

方法1:使用global声明全局变量(简单直接,不推荐复杂场景)

在函数内部用global关键字声明变量为全局变量,告诉Python不要将其视为局部变量:

import math
from functools import reduce

current_max_cosine_similarity_score = -math.inf

def func(acc, v):
  global current_max_cosine_similarity_score  # 声明为全局变量
  calculated_cosine_similarity_score = ...  # 计算逻辑

  if calculated_cosine_similarity_score > current_max_cosine_similarity_score:
    current_max_cosine_similarity_score = max(current_max_cosine_similarity_score, calculated_cosine_similarity_score)
    acc['cosineSimilarityScore'] = calculated_cosine_similarity_score
  
  return acc


print(reduce(func, [...], {}))

注意:全局变量易引发副作用,代码复杂度较高时不建议使用。

方法2:将最大值存入累加器acc(推荐,符合reduce设计思想)

reduce的累加器acc原本就是用来传递迭代状态的,将最大值存入acc无需全局变量,是更符合Python函数式编程风格的做法:

import math
from functools import reduce

def func(acc, v):
  calculated_cosine_similarity_score = ...  # 计算逻辑

  # 从acc中读取当前最大值,未初始化时用-math.inf作为默认值
  current_max = acc.get('current_max', -math.inf)
  if calculated_cosine_similarity_score > current_max:
    current_max = calculated_cosine_similarity_score
    acc['cosineSimilarityScore'] = current_max
    acc['current_max'] = current_max  # 更新acc中的最大值状态
  
  return acc


# 初始acc需包含current_max的初始状态,或在函数内处理默认值
print(reduce(func, [...], {'current_max': -math.inf}))

该方法无全局变量,所有状态通过累加器传递,代码清晰且无副作用,适配reduce的使用场景。

方法3:用类封装状态(适合复杂逻辑场景)

若后续逻辑需跟踪更多状态,可通过类封装相关变量和操作:

import math
from functools import reduce

class CosineTracker:
    def __init__(self):
        self.current_max = -math.inf
    
    def update(self, acc, v):
        calculated_score = ...  # 计算逻辑
        if calculated_score > self.current_max:
            self.current_max = calculated_score
            acc['cosineSimilarityScore'] = self.current_max
        return acc

tracker = CosineTracker()
print(reduce(tracker.update, [...], {}))

内容的提问来源于stack exchange,提问作者Amechi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:45:34