将.ipynb转.exe后出现NameError: name 'null' is not defined问题求助
问题
我用PyInstaller把.ipynb文件转成.exe,想让同事不用装Python就能用,但运行生成的.exe时弹出错误:
Traceback (most recent call last): File "Bot.ipynb", line 232, in NameError: name 'null' is not defined
有两个关键情况需要说明:
- 我的代码里完全没用到
null关键字 - 我写的代码总行数连232行都不到
我的代码如下:
from tkinter import * import PIL from PIL import ImageTk from PIL import Image import tkinter as tk import webbrowser from tkinter import scrolledtext from datetime import datetime root = tk.Tk() def update_title(): current_date_time = datetime.now().strftime("%A,%d-%b-%Y %H:%M:%S") root.title(f"Welcome - {current_date_time}") root.after(1000, update_title) update_title() root.geometry("1000x700") root.configure(bg="#D22730") def open_website(url): webbrowser.open(url) # 处理用户输入并生成机器人回复的函数 def get_bot_response(): user_input = input_box.get("1.0", tk.END).strip().lower() output_box.configure(state='normal') output_box.delete("1.0",tk.END) # 清除之前的输出 output_box.insert(tk.END, 'User: {}\n'.format(user_input)) # 根据用户查询提供对应指引 if 'how to register to ekincare' in user_input or 'ekincare' in user_input or 'medicine' in user_input or 'tele-medicine' in user_input: instructions = "partnered with ekincare, a leading digital healthcare provider \ to provide you with 24/7 unlimited access to doctor consultation. The coverage is for the \ employee and upto 5 family members. \n\n" instructions += "The key services provided are: \n" instructions += "1. 24/7 unlimited teleconsultation – (General Physician only) via chat or audio \n" instructions += "2. Health Risk Assessment – Track your and your family’s health \n" instructions += "3. COVID Care Management- Home Isolation support for COVID treatment \n" instructions += "4. Discounted Pharmacy – Up to 20% discount on medicines ordered online (borne by the employee) \n" instructions += "5. Discounted Medical Tests - Up to 40% discount on home sample collection (borne by the employee) \n" instructions += "6. For any queries / support required, please reach out to ekincare at help@ekincare.com or call at +91 49 6816 7274 \n" instructions += "7. For more details, please refer: https://hrdirect.service-now.com/sys_attachment.do?sys_id=f3c0bd451b37959868314376b04bcbf9 \n" response = instructions elif 'how to add a new domestic beneficiary using mobile banking app' in user_input or 'payee' in user_input or 'add beneficiary' in user_input: instructions = "To add new benefiary, please follow the below steps. \n\n" instructions += "1. Login to your Mobile Banking App \n" instructions += "2. Select 'Move Money' tab \n" instructions += "3. Select 'Pay & Transfer' \n" instructions += "4. Choose the account you’re making the payment from \n" instructions += "5. Under the 'my beneficiaries' section Now you’ll see an option to 'Add a new beneficiary' at the top of your screen \n" instructions += "6. Select and follow the onscreen instructions \n" instructions += "7. 'Confirm' your instruction \n" response = instructions else: response = "Sorry, I need to get trained on this topic" output_box.insert(tk.END, 'Bot: {}\n'.format(response)) output_box.configure(state='disabled') output_box.see(tk.END) input_label = tk.Label(root, text="User Input:",anchor="w",bg="black",fg="white",font=("Arial",12)) input_label.pack(anchor="w") # 输入框 input_box = scrolledtext.ScrolledText(root, height=7, width=100,font=("Arial",12)) input_box.pack() output_label = tk.Label(root, text="Bot Response:",anchor="w",bg="black",fg="white",font=("Arial",12)) output_label.pack(anchor="w") # 输出框 output_box = scrolledtext.ScrolledText(root, height=15,width=100,wrap=tk.WORD,font=("Arial",12)) output_box.pack() output_box.configure(borderwidth=1, relief="solid") send_button = tk.Button(root, text="Find", command=get_bot_response,bg="black",fg="white",width=8,height=1, font=("Arial",12,"bold")) send_button.pack() button_frame = tk.Frame(root) button_frame.pack(side="bottom",pady=10) button1 = tk.Button(root, text="Service now", relief="flat",width=15, height=1,font=("Arial",10,"bold"),command=lambda: open_website("https://itid.service-now.com/servicenow")) button1.pack(side="left",padx=5) root.mainloop()
完整回溯信息见截图:
解决方案
问题根源
直接用PyInstaller打包.ipynb文件是问题的核心——Jupyter笔记本本质是JSON格式的文件,里面不仅有你写的代码,还有输出记录、元数据等内容,而JSON里的空值标记是null。PyInstaller会把整个.ipynb文件当作Python脚本解析,自然会把JSON里的null识别成未定义的Python变量,报错里的行号也是JSON文件的行号,不是你写的代码行号。
解决步骤
把.ipynb转换成纯.py文件
- 图形化方式:打开Jupyter Notebook,点击菜单栏
File→Download as→Python (.py),直接导出纯Python脚本。 - 命令行方式:执行以下命令完成转换:
jupyter nbconvert --to script Bot.ipynb
转换后会得到
Bot.py文件,里面只有你的代码,没有多余的JSON元数据。- 图形化方式:打开Jupyter Notebook,点击菜单栏
验证转换后的.py文件
先在Python环境里运行python Bot.py,确认代码能正常启动、功能正常,没有报错。用PyInstaller打包.py文件
执行打包命令:pyinstaller --onefile Bot.py如果需要生成无控制台的窗口程序,加上
--windowed参数:pyinstaller --onefile --windowed Bot.py测试最终的.exe文件
打包完成后,在生成的dist文件夹里找到Bot.exe,运行测试,这个时候就不会再出现null未定义的错误了。
内容的提问来源于stack exchange,提问作者Atul sanwal
相关产品推荐
相关产品推荐

