zoukankan      html  css  js  c++  java
  • flask使用blinker信号机制解耦业务代码解决ImportError: cannot import name 'app',以异步发送邮件为例

    百度了大半天,不知道怎么搞,直到学习了blinker才想到解决办法,因为之前写java都是文件分开的,

    所以发送邮件业务代码也放到view里面,但是异步线程需要使用app,蛋疼的是其他模块不能从app.py导入任何变量:

    即: 

    app.py是主文件,view.py是业务文件, 我需要在view中使用app中的变量,怎么办,百度了很多,没有找到方法

    这里可以用信号实现,先记录一下:

    python3内置了blinker,可以直接使用,首先在view里定义信号:

    然后在app.py里面连接需要使用的函数(这个函数需要使用app,所以只能写在appp.py里),app是可以导入其他模块的变量的:

    # Flask-Mail 中的 send() 函数使用 current_app ,因此必须激活程序上下文。
    # 不过,在不同线程中执行 mail.send() 函数时,程序上下文要使用 app.app_context() 人工创建
    def send_async_email(msg):
        print("---开始发送---")
        with app.app_context():
            mail.send(msg)
    
    
    # 导入view 的信号量,并连接异步发送函数
    signal.connect(send_async_email)


    # 高版本可以直接通过注解实现

    # Flask-Mail 中的 send() 函数使用 current_app ,因此必须激活程序上下文。
    # 不过,在不同线程中执行 mail.send() 函数时,程序上下文要使用 app.app_context() 人工创建
    @signal.connect # 可以直接通过注解绑定函数
    def send_async_email(msg):
    print("---开始发送---")
    with app.app_context():
    mail.send(msg)

    最后view使用信号调用app的函数:

    @user.route('/sendsync/')
    def send_sync_mail():
        msg = Message(subject="Hello World!",
                      sender="799827577@qq.com",
                      recipients=["799827577hou@gmail.com"])
        msg.body = "测试异步发送"
        msg.html = "<h2>测试异步发送</h2>"
        thr = Thread(target=signal.send, args=[msg,])
        thr.start()
        return "ok"

    最后测试成功:

    这里还可以使用sender只接受指定参数,比如:

    只有当参数是2时候,才会进入round_two方法

  • 相关阅读:
    StringBuffer
    判断java标识符
    基本数据类型和String相互转换
    使用String
    Properties属性文件
    Map排序
    java集合之三映射:HashMap、Hashtable、LinkedHashMap、TreeMap
    列表、集合与数组之间相互转换
    自定义列表排序
    ML-支持向量:SVM、SVC、SVR、SMO原理推导及实现
  • 原文地址:https://www.cnblogs.com/houzheng/p/10990372.html
Copyright © 2011-2022 走看看