推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
IurNusRay
0.54D
V2EX  ›  Python

Django 中 Signal 的意义是什么

  •  
  •   IurNusRay · Mar 10, 2021 · 3437 views
    This topic created in 1900 days ago, the information mentioned may be changed or developed.
    试了一下 Django 自带的 Signal 模块,也并不能异步啊,而且又是在框架内发送 /接收消息,那么它存在的意义就单纯是为了代码解耦吗?如果这样干嘛不直接写个普通函数呢..
    14 replies    2021-03-31 17:49:07 +08:00
    twotiger
        1
    twotiger  
       Mar 10, 2021
    是的就是解耦。
    我个人也很少用到这个,不过之前的公司用来删除数据时,做一些操作。
    这种东西也就是一种设计模式,用好了,写的很好看,用的不好,还不如不写。
    xiaolinjia
        2
    xiaolinjia  
       Mar 10, 2021
    确实就是解耦,而之所以不写个普通函数,大概是因为传参很麻烦。
    yemoluo
        3
    yemoluo  
       Mar 10, 2021
    普通函数会涉及到声明的地方和调用的地方,这两者可能会高度耦合的。这边 import 一下 那边 import 一下。

    信号就不一样了,信号不用管谁接收,发出去即可。接收的地方也不用管谁发的,收到消息处理即可
    IurNusRay
        4
    IurNusRay  
    OP
       Mar 10, 2021
    @GTim 可是似乎用能信号来实现的功能,用普通函数来实现也可以啊,信号好像没没什么优势。比如我在收到客户端的点赞、评论、回复等请求的时候,要向指定用户发送消息提醒,那么我完全可以写一个公共函数,接收用户 id 、消息内容,然后发送消息,这个函数也可以在全局所有地方导入、调用,并没有什么缺点啊。。
    GeruzoniAnsasu
        5
    GeruzoniAnsasu  
       Mar 10, 2021   ❤️ 2
    想象一下 UI 编程。
    把 click 看成一个 signal,http 模块把现在文本框的内容 post 出去作为 slot

    显然在 button 的 onclick handler 里完全没必要实例化一个 http requester,从某个全局区获取一个 requester 再进行请求则更显怪异。优雅的做法当然是让 click 只作为一个信号灯,我们找一个第三者视角,看到灯亮的时候指使 http 模块发出请求。在第三者的上帝视角里能看到 button 的实例与 http 模块的实例,而 button 和 http 相互并不需要知道对方的实例存在。

    这是 qt 框架最基本的事件响应机制。基本上有 signal 这个概念的框架设计理念都是类似的。
    IurNusRay
        6
    IurNusRay  
    OP
       Mar 10, 2021
    @GeruzoniAnsasu 好像有点明白了,谢谢
    est
        7
    est  
       Mar 10, 2021
    > 如果这样干嘛不直接写个普通函数呢..

    因为你手上的业务不够多。。

    等你一个函数内部同时服务 3 、5 个需求方的时候,就知道麻烦了。
    coolair
        8
    coolair  
       Mar 10, 2021
    这个是我很喜欢 Django 的一点……太好用了,太方便了。
    2owe
        9
    2owe  
       Mar 10, 2021
    Signal,就是一种“注册-发布-订阅”的功能实现。

    Django 框架对外提供了一些信号,比如 post_save

    Ps. 想要异步的话,可以自己加 celery 改造
    23333333333
        10
    23333333333  
       Mar 10, 2021
    其实最大的作用就是解耦

    举个例:子 更新 cache

    * 有个函数去接 post_save 的信号,接到这个信号之后去删除对应的 cache,而不是每次手动去操作
    hj24
        11
    hj24  
       Mar 10, 2021
    确实只能解耦,你把代码写到一个函数里也是一样的,之前用 go 重构这种代码的时候基本都是写回到一个函数里
    acmore
        12
    acmore  
       Mar 10, 2021
    类似于(或者就是) Mediator pattern
    小项目用这个没有啥显著收益,直接普通函数完全没问题。
    大项目的好处楼上已经说得很全面了。

    但它会造成调用方和服务提供方在语法上的隔离,不是完美也不是唯一的方案。
    zachlhb
        13
    zachlhb  
       Mar 10, 2021 via iPhone
    逻辑解耦,比如完成一个操作后需要执行其他操作,而这些操作可能现在不确定或不是由你开发的,这时就需要用到信号,一个信号可以有多个接收者,这个很好管理,如果需要异步,可以在信号接收逻辑里派发异步任务
    zepc007
        14
    zepc007  
       Mar 31, 2021
    实际用处并不大,又不是异步,只不过是对数据处理提供一种 hook 方式
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2670 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 70ms · UTC 10:55 · PVG 18:55 · LAX 03:55 · JFK 06:55
    ♥ Do have faith in what you're doing.