为什么代码似乎定义了,但为什么仍收到行错误

时间:2018-12-06 00:26:45

标签: python

我有一个

组成的grade.txt。
Mickey,Mouse,90*
Jane,Doe,50
Minnie,Mouse,95
Donald,Duck,80
Daffy,Duck,70

在计算平均值时,尝试读取文件并拆分以分开名称和等级。我收到未定义的行。

def main ():
  with open('grade.txt' , 'r') as f:
    lines = f.readlines(); #reads all the line in file to lines list.

  f.close(); #closes f stream.

sum = 0; #initialised sum to store the sum of all grades.

print('Name    Grade');

print('--------------------');

for line in lines: #loops through the lines list

  str = line.split(','); #splits each line based on ','

  grade = int(str[2]); #converts string to numeric value.

  sum += grade; #adds the grade value to sum.

  print(str[0]," ",str[1]," ",grade); #prints the line read after splitting.

print('Average Grade: ',round((sum/len(lines)),1)); #prints average of all grades by rounding it to 1 place.

newdata = input('Enter firstname,lastname and grade: '); #prompts user.

with open('grade.txt', 'a') as f: #opens file in append mode.

  f.write('\n'+newdata); #writes data into file in new line.

f.close(); #closes f stream
main ()

朝着正确方向的协助表示赞赏。

出现错误

 Traceback (most recent call last):
 File "main.py", line 13, in <module>
 for line in lines: #loops through the lines list
 NameError: name 'lines' is not defined

修改后的代码

def main ():
  with open('grades.txt' , 'r') as f:
    lines = f.readlines(); #reads all the line in file to lines list.

  sum = 0; #initialised sum to store the sum of all grades.

  print('Name    Grade');

  print('--------------------');

  for line in lines: #loops through the lines list

    str = line.split(','); #splits each line based on ','

    grade = int(str[2]); #converts string to numeric value.

    sum += grade; #adds the grade value to sum.

    print(str[0]," ",str[1]," ",grade); #prints the line read after splitting.

  print('Average Grade: ',round((sum/len(lines)),1)); #prints average of all grades by rounding it to 1 place.

newdata = input('Enter firstname,lastname and grade: '); #prompts user.

with open('grades.txt', 'a') as f: #opens file in append mode.

  f.write('\n'+newdata); #writes data into file in new line.

f.close(); #closes f stream

谢谢,我通过缩进传递了行错误,并删除了f.close;。通过,我看到我的代码没有输出文件的内容。这只是打印newdata

2 个答案:

答案 0 :(得分:1)

创建lines之类的变量时,只能在创建它的函数中使用它。

您的主函数实际上在行f.close();之后结束。为了使一切成为您的主要功能的一部分,您需要保持相同的缩进级别。

def main ():
  with open('grade.txt' , 'r') as f:
    lines = f.readlines(); #reads all the line in file to lines list.

  f.close(); #closes f stream.

  sum = 0; #initialised sum to store the sum of all grades.

  print('Name    Grade');

  print('--------------------');

  for line in lines: #loops through the lines list

    str = line.split(','); #splits each line based on ','

    grade = int(str[2]); #converts string to numeric value.

    sum += grade; #adds the grade value to sum.

    print(str[0]," ",str[1]," ",grade); #prints the line read after splitting.

  print('Average Grade: ',round((sum/len(lines)),1)); #prints average of all grades by rounding it to 1 place.

  newdata = input('Enter firstname,lastname and grade: '); #prompts user.

  with open('grade.txt', 'a') as f: #opens file in append mode.

    f.write('\n'+newdata); #writes data into file in new line.

  f.close(); #closes f stream
main ()

与您的代码有关的几个指针。在Python中,每行的末尾不需要分号。

使用f.close()块时,不需要行with。该文件在with块的结尾处自动关闭。

答案 1 :(得分:0)

它与可变范围有关。

with open('grade.txt', 'r') as f:
    lines = f.readlines()

是在with语句内定义的,因此在with语句退出(文件关闭)时不再存在。

根据您的缩进以及因此可变的范围,在“使用”行的位置很重要。

with open('grade.txt', 'r') as f:
    lines = f.readlines()

    # "lines" is visible here.
    do_something_here()

# "lines" is not defined here.
for line in lines:
    wont_work()

但是,如果在with语句之外定义行,则代码将起作用。这可以改变“行”的范围,并使其在整个with语句中持续存在,尽管这可以说是更松散的代码。例如:

lines = []
with open('grade.txt', 'r') as f:
    lines = f.readlines()

# lines persists and now contains the content of the file. So you can still operate on it.
do_something_here()

简单的解决方案:

def main():
    print("Name               Grade")
    print('-------------------------')

    with open('grade.txt', 'r') as file:
        sum = 0
        count = 0

        for line in file:
            # Strip the line of all white space and new lines "\n" usually found in text files.
            # Also strip the "*" found in the original input file.
            # Split content based on ",".
            entry = line.strip().strip("*").split(',')

            # Extract name and grade.
            name = entry[0] + " " + entry[1]
            grade = entry[2]

            print("{:<20}{:>2}".format(name, grade))

            sum += int(grade)
            count += 1

        print("Average Grade:      {:.1f}".format(sum / count))


if __name__ == '__main__':
    main()

有关Python的说明:

  1. 您不需要分号;。
  2. 尝试使用4个空格进行缩进。采用 [PEP 8(https://www.python.org/dev/peps/pep-0008/)准则。
  3. 使用“ with”时不需要使用file.close()。该文件将自动关闭。搜索with语句在Python中的工作方式:http://effbot.org/zone/python-with-statement.htm
  4. 如果您的文本文件是HUUUUUUUGE,则执行file.readlines()会将其立即全部加载到内存中。如果您遇到问题,一次遍历文件中的每一行:
with open('grade.txt', 'r') as file:
    for line in file:
        # efficient memory usage
        do_something
print(type(file))

输出:

<class '_io.TextIOWrapper'>