【问题标题】:UnBoundLocalError: local variable referenced before assignment (Python)UnBoundLocalError:赋值前引用的局部变量(Python)
【发布时间】:2015-06-14 12:00:08
【问题描述】:

我正在尝试创建一个函数servo_to_quadrant,它返回值servo_quadrant

与此类似的问题涉及函数外部的全局变量存在问题。在这种情况下,我认为这不是问题,因为仅在函数内部需要变量(尽管我可能是错的)。

代码:

def servo_to_quadrant(servo_val):
    if servo_val < 0: 360 + servo_val
    if servo_val >= 360: servo_val = servo_val - 360
    if servo_val >= 0 and servo_val < 90: servo_quadrant = 1
    if servo_val >= 90 and servo_val < 180: servo_quadrant = 2
    if servo_val >= 180 and servo_val < 270: servo_quadrant = 3
    if servo_val >= 270 and servo_val < 360: servo_quadrant = 4
    return servo_quadrant

servo_val = -30
quadrant = servo_to_quadrant(servo_val)
print(quadrant)

错误:

Traceback (most recent call last):
  File "test2.py", line 11, in <module>
    quadrant = servo_to_quadrant(servo_val)
  File "test2.py", line 8, in servo_to_quadrant
    return servo_quadrant
UnboundLocalError: local variable 'servo_quadrant' referenced before assignment

【问题讨论】:

  • 只需在函数开始时将其初始化为某个值。像这样servo_quadrant = 0
  • 也许您可以只返回所需的值,而不是使用伺服象限变量。喜欢if servo_val &lt; 0: return 360 + servo_val
  • Zlopez - servo_quadrant = 0 似乎返回了 0,就好像它跳过了所有的 if 函数一样。 artemdevel - 我试图推断servo_val 落入的象限。

标签: python variables variable-assignment local


【解决方案1】:

这是因为您在函数中的前面if 条件之一下分配了变量servo_quadrant,如果没有任何条件返回True,您将没有任何servo_quadrant。为了解决这个问题,你需要在你的函数中初始化这个变量。

您可以将servo_quadrant = 0 放在函数的顶层,也可以在返回任何内容之前检查servo_quadrant 的值:

if servo_quadrant :
    return servo_quadrant
return None

另外注意你需要重新分配变量servo_val

if servo_val < 0: servo_val=360 + servo_val

演示:

def servo_to_quadrant(servo_val):
    servo_quadrant=0
    if servo_val < 0: servo_val=360 + servo_val
    if servo_val >= 360: servo_val = servo_val - 360
    if servo_val >= 0 and servo_val < 90: servo_quadrant = 1
    if servo_val >= 90 and servo_val < 180: servo_quadrant = 2
    if servo_val >= 180 and servo_val < 270: servo_quadrant = 3
    if servo_val >= 270 and servo_val < 360: servo_quadrant = 4
    return servo_quadrant

servo_val = -30
quadrant = servo_to_quadrant(servo_val)
print quadrant

结果:

4

【讨论】:

  • 我在函数的第一行添加了servo_quadrant = 0,但它似乎返回0 - 好像它跳过了if语句。前两个if语句将servo_val修改为在 0 到 360 的范围内,以便使用后面的 if 语句。
  • @l87q4t 您需要在第一个 if 中重新分配它:因此将条件更改为 servo_val=360 + servo_val
  • 哎呀……我真傻。它现在可以工作(不需要servo_quadrant=0)。谢谢:)
【解决方案2】:

在尝试返回函数之前,您需要确保在函数的每条路径中分配 servo_quadrant

def servo_to_quadrant(servo_val):
    if servo_val < 0: 360 + servo_val # <--- This does nothing
    if servo_val >= 360: servo_val = servo_val - 360 # <--- This assumes servo_val < 720
    if servo_val >= 0 and servo_val < 90: servo_quadrant = 1
    if servo_val >= 90 and servo_val < 180: servo_quadrant = 2
    if servo_val >= 180 and servo_val < 270: servo_quadrant = 3
    if servo_val >= 270 and servo_val < 360: servo_quadrant = 4
    # At this point, servo_quadrant may still not have been assigned
    return servo_quadrant

如果要将servo_val 移动到0&lt;=servo_val&lt;360 范围内,可以使用取模运算符。
而且您可以利用这样一个事实,即如果您从函数返回,则无需继续检查相同的条件。

def servo_to_quadrant(servo_val):
    servo_val %= 360
    if servo_val < 90: return 1
    if servo_val < 180: return 2
    if servo_val < 270: return 3
    return 4

【讨论】:

  • 我添加了前两个 if 语句,以便修改 servo_val 使其值在 0 和 360 之间,以便与它后面的 if 函数一起使用。
  • 这一行:if servo_val &lt; 0: 360 + servo_val 没有修改servo_val。这行:if servo_val &gt;= 360: servo_val = servo_val - 360 不一定会将servo_val 移动到预期范围内,除非您知道servo_val 不能超过 720。
  • 我应该多加注意的。不过还是谢谢。
【解决方案3】:

这是因为您尝试修改未在您的函数中定义的伺服象限。如果你只是读取一个变量,Python 默认使用全局作用域。因此,如果您不修改它,一切都会正常工作。如果您需要修改它,只需在函数开头添加global servo_quadrant

【讨论】:

  • 添加global servo_quadrant是否意味着它成为一个全局变量?我希望将其保留在函数的本地,因为我打算一次运行函数的多个实例(此代码是较大代码的一部分)。
  • 是的,它将在全局范围内,在您的情况下,最好将其初始化为其他 cmets 中提到的某个值。
  • 其他人指出问题在于我忘记添加将修改servo_val 以适应 0 和 360 的代码(在前两个 if 语句中),但还是谢谢你。
猜你喜欢
  • 2018-06-29
  • 1970-01-01
  • 2012-11-14
  • 2013-11-29
  • 2019-09-02
  • 1970-01-01
  • 2011-10-31
  • 2020-05-05
  • 1970-01-01
相关资源
最近更新 更多