Python UnboundLocalError:从文件读取时在赋值之前引用了局部变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15367760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:55:27  来源:igfitidea点击:

UnboundLocalError: local variable referenced before assignment when reading from file

python

提问by user1958508

I have also tried searching for the answer but I don't understand the answers to other people's similar problems...

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

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)

I get the following error

我收到以下错误

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

The first print statement works correctly but it won't work for the second. I have tried making T a global variable but this makes both answers the same! Please help!

第一个打印语句正常工作,但不适用于第二个。我曾尝试将 T 设为全局变量,但这会使两个答案相同!请帮忙!

采纳答案by shx2

Your ifstatement is always false and T gets initialized only if a condition is met, so the code doesn't reach the point where Tgets a value (and by that, gets defined/bound). You should introduce the variable in a place that always gets executed.

您的if语句始终为 false,并且 T 只有在满足条件时才会初始化,因此代码不会到达T获取值的点(并且由此被定义/绑定)。您应该在始终执行的地方引入变量。

Try:

尝试:

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

回答by brandonsimpkins

Before I start, I'd like to note that I can't actually test this since your script reads data from a file that I don't have.

在开始之前,我想指出的是,我实际上无法对此进行测试,因为您的脚本从我没有的文件中读取数据。

'T' is defined in a local scope for the declared function. In the first instance 'T' is assigned the value of 'data[2]' because the conditional statement above apparently evaluates to True. Since the second call to the function causes the 'UnboundLocalError' exception to occur, the local variable 'T' is getting set and the conditional assignment is never getting triggered.

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

Since you appear to want to return the first bit of data in the file that matches your conditonal statement, you might want to modify you function to look like this:

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

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

That way the desired value gets returned when it is found, and 'None' is returned when no matching data is found.

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

回答by javex

The other answers are correct: You don't have a default value. However, you have another problem in your logic:

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

You read the same file twice. After reading it once, the cursor is at the end of the file. To solve this, you can do two things: Either open/close the file upon each function call:

你读了两次同一个文件。读取一次后,光标位于文件末尾。为了解决这个问题,你可以做两件事:在每次函数调用时打开/关闭文件:

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

This hase the disadvantage of having to open the file each time. The better way would be:

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

tfile.seek(0)

You do this after your for line in tfile:loop. It resets the cursor to the beginning to the next call will start from there again.

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

回答by Dan H

FWIW: I got the same error for a different reason. I post the answer here not for the benefit of the OP, but for the benefit of those who may end up on this page due to its title... who might have made the same mistake I did.

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

I was confused why I was getting "local variable referenced before assignment" because I was calling a FUNCTION that I knew was already defined:

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

def job_fn(job):
  return job + ".job"

def do_something():
  a = 1
  b = 2
  job_fn = job_fn("foo")

do_something()

This was giving:

这是给:

UnboundLocalError: local variable 'job_fn' referenced before assignment

Took me a while to see my obvious problem: I used a local variable named job_fnwhich masked the ability to see the prior function definition for job_fn.

我花了一段时间才看到我的明显问题:我使用了一个名为的局部变量job_fn,它掩盖了查看job_fn.

回答by Lali

I was facing same issue in my exercise. Although not related, yet might give some reference. I didn't get any error once I placed addition_result = 0 inside function. Hope it helps! Apologize if this answer is not in context.

我在练习中遇到了同样的问题。虽然不相关,但可以提供一些参考。一旦我在函数中放置了 added_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)

回答by Greg Vazquez

Contributing to ferrix example,

贡献于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)

My message will not execute, because none of my conditions are fulfill therefore receiving " UnboundLocalError: local variable 'range' referenced before assignment"

我的消息将不会执行,因为我的条件都不满足,因此收到“UnboundLocalError:分配前引用的局部变量‘范围’”

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

回答by Mihit Gandhi

To Solve this Error just initialize that variable above that loop or statement. For Example var a =""

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