python - 异常触发:“NoneType”对象没有属性“app”
问题描述
使用 Python3 和 Flask 时出错。
在下面显示的代码中,您会注意到我已将端口定义为 8080。将其定义为端口 80 在我拥有的另一个应用程序中运行良好,该应用程序可以浇灌我的室内植物并在动态网页上显示结果,但在这里它因权限被拒绝错误而崩溃。为什么,鉴于两者都是在 Raspbian 上使用相同版本以完全相同的方式创建的?
但这还不是问题。真正的问题是为什么它甚至不能在同一个应用程序中保持一致。
#!/usr/bin/python3
from flask import Flask, render_template, redirect, url_for
from imapclient import IMAPClient
import email
import time
import sys
import os
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(1) # number of executor
import logging
logging.basicConfig(filename='/home/pi/mailbox_event.log',level=logging.WARNING)
HOSTNAME = 'imap.plus.net'
USERNAME = 'megapower+rob'
PASSWORD = 'aqp-hRM-2Nb-qh9'
MAILBOX = 'INBOX'
NEWMAIL_OFFSET = 0
MAIL_CHECK_FREQ = 10 #number of seconds for mail check
m1 = ""
m2 = ""
m3 = ""
m4 = ""
app = Flask(__name__)
def TimeNowIs():
TimeNow = time.strftime('%d/%m/%Y at %H:%M:%S')
return TimeNow
print("Hi" )
print("Mailbox here")
print("Just starting up")
logging.info("Mailbox App starting up")
def template(title = "Mail Display!", text = TimeNowIs(), m1 = " ", m2 = " ", m3 = " ", m4 = " "):
text, m1, m2, m3, m4 = ""
templateData = {
'title' : title,
'text' : text,
'm1' : m1,
'm2' : m2,
'm3' : m3,
'm4' : m4
}
return templateData
@app.route("/")
def main():
text = TimeNowIs()
m1 = "Hi"
m2 = "Mailbox here"
m3 = "Just starting up"
m4 = "Going to check your mail"
list_object = [text, m1, m2, m3, m4]
return render_template('main.html', text_to_send = list_object)
def getmail():
try:
print("Logging in")
server = IMAPClient(HOSTNAME, use_uid=True, ssl=False)
server.login(USERNAME, PASSWORD)
server.select_folder('INBOX', readonly=True)
except:
connected = False
server = ""
logging.warning('Logon failed')
print("Logon failed")
else:
connected = True
print("Logon succeeded")
messages = server.search('UNSEEN')
print("we have %d unread emails." % len(messages))
for uid, message_data in server.fetch(messages, 'RFC822').items():
email_message = email.message_from_bytes(message_data[b'RFC822'])
m1 = (uid, email_message.get('From'), email_message.get('Subject'))
print(m1)
text = TimeNowIs()
m1 = "Well now"
m2 = "I've checked your mail"
m3 = "you should see something here"
m4 = "that isn't the start up message"
list_object = [text, m1, m2, m3, m4]
print("Logging out")
server.logout()
return render_template('main.html', text_to_send = list_object)
def printmail():
try:
while True:
os.system("clear")
timeString = time.strftime('%d/%m/%Y at %H:%M:%S')
print("Checking mail")
print(timeString)
getmail()
print("Waiting")
time.sleep(MAIL_CHECK_FREQ)
except KeyboardInterrupt:
print("Shutting down")
logging.info('System closed by Ctrl-C')
print("Goodbye")
#os.system("sudo reboot")
except Exception as e:
logging.warning('Exception triggered: ' + str(e))
print("Exception triggered: " + str(e))
# os.system("sudo reboot")
pass
return
if __name__ == "__main__":
executor.submit(printmail)
app.run(host='0.0.0.0', port=8080, debug=True)
我在这里努力的是 printmail() 作为永恒循环运行的场景,除非被杀死或发生致命异常,然后将记录该异常,然后 Pi 重新启动。您将从所附图像中看到 main() 运行并且 list_object 被写入网页。
但是,当调用 getmail() 时,m1 会被写入终端,所以我知道我们可以到那里,但是 render_template 失败,'NoneType' 对象没有属性'app'。
我想知道自从返回 render_template 行之后会怎样,并且创建 list_object 的代码与 main() 中的代码相同
解决方案
Flask render_template 函数期望能够访问flask 应用程序上下文。你可以在这里看到 render_template 的实现: https ://github.com/pallets/flask/blob/1351d0a56580df36872b466eb245e7634c20dab5/src/flask/templating.py#L125-L141
from .globals import _app_ctx_stack
ctx = _app_ctx_stack.top
ctx.app.update_template_context(context)
return _render(
ctx.app.jinja_env.get_or_select_template(template_name_or_list),
context,
ctx.app,
)
您需要找到一种方法让您的执行程序线程可以访问烧瓶本地堆栈上下文。
推荐阅读
- firebase - 如何触发 Firebase 云功能以添加用户、生成密码并使用该密码发送邮件
- excel - 计算波形周期并计算频率
- angular - New buildable angular library can not be build
- winforms - Powershell GUI 自动生成具有功能的按钮
- javascript - React - TypeError:jokes.map 不是函数
- java - 在 java 中指定文件路径会导致 FileNotFoundException
- c - 如何从 C 中的 struct 打印,我不确定我做错了什么,并且不断从代码的所有部分得到各种错误?
- flutter - 如何在颤动中将语音传递到文本字段?
- php - 在用户提交 html 注册表单时通过电子邮件向用户发送确认信息
- c++ - 为什么“if (unsigned int == string::npos)”可以是真的?