Python图书馆管理系统访问跨函数bkd字典报NameError如何解决
问题原因
你遇到的NameError是两个问题共同导致的:
- 你在
crt_book_rec()函数内部定义的bkd是局部变量,只能在该函数内部访问,其他函数(包括crt_lib_rec())没有权限直接访问这个变量 - 你需要验证的图书ID都存储在
bookrec.dat文件中,你没有在crt_lib_rec()中读取该文件的内容生成有效的bkd字典,直接调用未定义的变量自然会报错
解决步骤
步骤1:新增公共读取图书记录的函数
因为你每次创建图书记录时,都是往bookrec.dat追加存储单条图书的字典,所以我们写一个通用函数,读取文件中所有的图书记录合并为一个总字典,方便所有需要用到图书数据的函数调用:
# 如果你还没导入pickle,把这行放到代码最开头 import pickle as p def load_all_books(): all_books = {} try: with open('bookrec.dat', 'rb') as f: # 循环读取文件中所有序列化的字典 while True: try: book_item = p.load(f) all_books.update(book_item) # 合并到总字典 except EOFError: break except FileNotFoundError: # 第一次运行还没有图书文件时返回空字典 return {} return all_books
步骤2:修改crt_lib_rec()函数
修改该函数,调用上面的公共函数拿到所有图书记录再做校验,同时用with语句自动处理文件关闭,避免资源泄漏:
def crt_lib_rec(): # 读取所有图书记录生成bkd字典 bkd = load_all_books() if not bkd: print("当前没有可借阅的图书,请先录入图书记录") return rec={} rno=int(input('Enter Rno: ')) nm=input('Enter name: ') gd=int(input("Enter the Grade of the student: ")) div=input("Enter the Class of the student: ") bookid=int(input("Enter the Book ID: ")) retdate=input("Enter the date of return: ") # 直接in字典就等价于判断是否在keys里,不用写.keys() if bookid in bkd: with open('library.dat','ab') as f: rec[rno]={'Name':nm,'Grade':gd,'Division':div,'Book ID':bookid,'Return Date':retdate} p.dump(rec,f) print("Record Created Successfully..") else: print("Enter a valid Book ID..")
步骤3:修改菜单函数的调用逻辑
你原来在menufn()里调用crt_lib_rec(bkd)时,menufn里也没有定义bkd变量,把传参删掉即可:
找到opt2=='1'的分支,将原来的调用代码改为:
crt_lib_rec()
可选优化(建议修改)
你原来的crt_book_rec()没有做重复ID校验,可以修改成先读已有记录,避免同一个图书ID重复录入:
def crt_book_rec(): all_books = load_all_books() bkid=int(input('Enter Book ID: ')) if bkid in all_books: print("该图书ID已存在,请换一个ID") return bknme=input('Enter Book Name: ') authnme=input("Enter Author Name: ") bkd={bkid: {'Book Name':bknme,'Author Name':authnme}} with open('bookrec.dat','ab') as g: p.dump(bkd,g) print("图书记录创建成功")
内容的提问来源于stack exchange,提问作者Keshav Nair
相关产品推荐
相关产品推荐

