【问题标题】:"UnboundLocalError: local variable referenced before assignment" after an if statementif 语句后的“UnboundLocalError:赋值前引用的局部变量”
【发布时间】:2013-02-28 08:26:24
【问题描述】:

我也试过寻找答案,但我不明白其他人类似问题的答案...

tfile= open("/home/path/to/file",'r') 

def temp_sky(lreq, breq):
    for line in tfile:
        data = line.split()
        if (    abs(float(data[0]) - lreq) <= 0.1 
            and abs(float(data[1]) - breq) <= 0.1):            
            T= data[2]
    return T
print temp_sky(60, 60)
print temp_sky(10, -10)

我收到以下错误

7.37052488
Traceback (most recent call last):
File "tsky.py", line 25, in <module>
  print temp_sky(10, -10)
File "tsky.py", line 22, in temp_sky
  return T
UnboundLocalError: local variable 'T' referenced before assignment

第一个打印语句可以正常工作,但第二个就不行了。我曾尝试将 T 设为全局变量,但这使得两个答案相同!请帮忙!

【问题讨论】:

  • 为了摆脱UnboundLocalError,if语句必须运行,所以尝试给T一个默认值以便定义T,参考@shx2答案
  • 另外,您正在运行整个循环来获取单个值。这样,您的循环将始终返回最后一个匹配的数据实例。您可以通过以相反的顺序阅读代码而不是分配 return T 来提高代码效率

标签: python


【解决方案1】:

您的if 语句始终为假,并且T 仅在满足条件时才被初始化,因此代码不会到达T 获得值的地步(由此,被定义/绑定) .你应该在一个总是被执行的地方引入变量。

试试:

def temp_sky(lreq, breq):
    T = <some_default_value> # None is often a good pick
    for line in tfile:
        data = line.split()
        if abs(float(data[0])-lreq) <= 0.1 and abs(float(data[1])-breq) <= 0.1:
            T = data[2]
    return T

【讨论】:

    【解决方案2】:

    FWIW:由于不同的原因,我得到了同样的错误。我在这里发布答案不是为了 OP 的利益,而是为了那些可能由于标题而最终出现在此页面上的人的利益……他们可能犯了与我相同的错误。

    我很困惑为什么我得到“在赋值之前引用的局部变量”,因为我正在调用一个我知道已经定义的 FUNCTION:

    def job_fn(job):
      return job + ".job"
    
    def do_something():
      a = 1
      b = 2
      job_fn = job_fn("foo")
    
    do_something()
    

    这是给予:

    UnboundLocalError: local variable 'job_fn' referenced before assignment
    

    我花了一段时间才发现明显的问题:我使用了一个名为 job_fn 的局部变量,它掩盖了查看 job_fn 先前函数定义的能力。

    【讨论】:

    【解决方案3】:

    其他答案是正确的:您没有默认值。但是,您的逻辑还有另一个问题:

    你读了同一个文件两次。读取一次后,光标位于文件末尾,因此再次尝试读取它不会返回任何内容,并且永远不会进入循环。要解决这个问题,您可以做两件事:在每次函数调用时打开/关闭文件:

    def temp_sky(lreq, breq):
        with open("/home/path/to/file",'r') as tfile:
            # do your stuff
    

    这样做的缺点是每次都必须打开文件。更好的方法是:

    tfile.seek(0)
    

    您在 for line in tfile: 循环之后执行此操作。它将光标重置到开头,以便下一次调用将再次从那里开始。

    相关问题:

    【讨论】:

    • 解决我的错误后,我仍然没有得到正确的答案,这是由于文件光标不在正确的位置。我已按照您的建议对此进行了修改,现在正在工作。谢谢
    【解决方案4】:

    在我开始之前,我想指出我无法实际测试这个,因为你的脚本从我没有的文件中读取数据。

    'T' 在声明函数的局部范围内定义。在第一个实例中,'T' 被分配了'data[2]' 的值,因为上面的条件语句显然评估为 True。由于第二次调用该函数会导致“UnboundLocalError”异常发生,因此局部变量“T”被设置并且条件赋值永远不会被触发。

    由于您似乎想要返回文件中与条件语句匹配的第一位数据,您可能希望将函数修改为如下所示:

    def temp_sky(lreq, breq):
        for line in tfile:
            data = line.split()
            if ( abs(float(data[0]) - lreq) <= 0.1 and abs(float(data[1]) - breq) <= 0.1):            
                return data[2]
        return None
    

    这样,当找到所需的值时,它就会返回,而当没有找到匹配的数据时,则返回“None”。

    【讨论】:

    • 这实际上不是相同的行为。给出的示例返回最后一个匹配的实例,而您将返回第一个实例。从末尾读取文件是可行的,但如果我们不希望整个文件都在内存中,那么简单的reversed() 就行不通了。
    【解决方案5】:

    我在练习中遇到了同样的问题。虽然不相关,但可以提供一些参考。将addition_result = 0 放入函数后,我没有收到任何错误。希望能帮助到你!如果此答案与上下文无关,请道歉。

    user_input = input("Enter multiple values separated by comma > ")
    
    def add_numbers(num_list):
        addition_result = 0
        for i in num_list:
            addition_result = addition_result + i
        print(addition_result)
    
    add_numbers(user_input)
    

    【讨论】:

      【解决方案6】:

      贡献 ferrix 示例,

      class Battery():
      
          def __init__(self, battery_size = 60):
              self.battery_size = battery_size
          def get_range(self):
              if self.battery_size == 70:
                  range = 240
              elif self.battery_size == 85:
              range = 270
      
              message = "This car can go approx " + str(range)
              message += "Fully charge"
              print(message)
      

      我的消息不会执行,因为我的条件都不满足,因此收到“UnboundLocalError: local variable 'range' referenced before assignment”

      def get_range(self):
          if self.battery_size <= 70:
              range = 240
          elif self.battery_size >= 85:
              range = 270
      

      【讨论】:

        【解决方案7】:

        要解决此错误,只需在该循环或语句上方初始化该变量。例如var a =""

        【讨论】:

        • 这是 Python,不是 JS
        猜你喜欢
        • 2012-11-14
        • 2013-11-29
        • 2019-09-02
        • 1970-01-01
        • 2015-06-14
        • 2018-06-29
        • 2011-10-31
        • 2020-05-05
        • 1970-01-01
        相关资源
        最近更新 更多