V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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
lanqing
V2EX  ›  Python

django 中如何维护一个全局变量

  •  
  •   lanqing · 2018-11-03 11:37:30 +08:00 · 6993 次点击
    这是一个创建于 2210 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我想在 django 中的任何一个地方都可以访问这个变量(比如这个变量是一个 list),我能够任意添加和删除变量中的元素,我原本想保存到 redis 中,但是我发现 redis 中好像只能存储字符串类型的,我想保存任意类型的对象到这个变量中,有什么办法么,不吝赐教,非常感谢!
    32 条回复    2019-08-28 16:05:40 +08:00
    xyxc0673
        1
    xyxc0673  
       2018-11-03 11:43:40 +08:00 via Android
    可以先序列化了再存进 redis 里
    qq976739120
        2
    qq976739120  
       2018-11-03 11:45:40 +08:00
    放到 settings 里去啊
    lanqing
        3
    lanqing  
    OP
       2018-11-03 11:50:57 +08:00
    @qq976739120 好像不行
    lanqing
        4
    lanqing  
    OP
       2018-11-03 11:51:08 +08:00
    @xyxc0673 用 pickle 可以序列化所有对象么
    absente
        5
    absente  
       2018-11-03 11:56:55 +08:00
    为啥要用全局变量?直接序列化存储到合适的地方不就好了。python 有 zodb,erlang 有 ETS。
    absente
        6
    absente  
       2018-11-03 11:57:36 +08:00
    zodb 比 pickle 稍微好用一点点,也可以直接存内存
    lolizeppelin
        7
    lolizeppelin  
       2018-11-03 11:59:34 +08:00 via Android
    单例 惰性初始化
    freakxx
        8
    freakxx  
       2018-11-03 12:04:41 +08:00
    @qq976739120
    他应该是要读写,settings 满足不了写这个操作


    你用 redis,可以先 json 进去,出来 loads 下就可以,
    或者用 model 的形式,建一个 config model,然后用 key,value 形式来处理;
    lanqing
        9
    lanqing  
    OP
       2018-11-03 12:13:05 +08:00
    @freakxx 我想存储的是 socket 对象,json 序列化好像不可以的
    lanqing
        10
    lanqing  
    OP
       2018-11-03 12:13:24 +08:00
    @absente 好的!我会看看这个东西,以前没看到过,谢谢
    absente
        11
    absente  
       2018-11-03 12:19:09 +08:00
    @lanqing 我替你试了一下,zodb 也不能存 socket,当然这主要是 picke 本身没有协议支持的原因(硬要支持也不是不可以)。建议还是自己写一个 middleware,把存 socket 的部分分离出来
    absente
        12
    absente  
       2018-11-03 12:20:58 +08:00
    pyramid 有一个 non tread safe 的方案可以解决这个问题,django 具体没试过,就不乱发言了。
    zxcvsh
        13
    zxcvsh  
       2018-11-03 12:23:50 +08:00 via iPhone
    settings
    Hopetree
        14
    Hopetree  
       2018-11-03 12:38:12 +08:00
    放到数据库
    jianmingforpc
        15
    jianmingforpc  
       2018-11-03 12:41:13 +08:00 via iPhone
    放 socket 还要修改啊..那看你的 wsgi server 是什么模式的?我觉得单进程的应该放 setting 可以...
    JasperYanky
        16
    JasperYanky  
       2018-11-03 12:41:54 +08:00 via iPhone
    django solo
    tabris17
        17
    tabris17  
       2018-11-03 13:05:16 +08:00
    任意类型是不可能的。因为操作系统的句柄在不同系统甚至不同进程中都没有意义。可序列化的数据类型还差不多
    fzleee
        18
    fzleee  
       2018-11-03 13:18:50 +08:00
    单进程的话,试试 threadlocal?
    spark
        19
    spark  
       2018-11-03 13:27:55 +08:00 via iPhone
    可以环境变量么
    iiduce
        20
    iiduce  
       2018-11-03 13:45:17 +08:00
    这种我就放数据库里。想放任意数据类型要用文件型数据库,我用的是 mongodb。
    lolizeppelin
        21
    lolizeppelin  
       2018-11-03 14:32:14 +08:00 via Android
    都说了用单例模式就行了

    简单点的 Python 模块本身就是单例的
    随便拿个专门模块来放这类变量就完了
    Gothack
        22
    Gothack  
       2018-11-03 15:09:28 +08:00 via iPhone
    processor ?
    lihongjie0209
        23
    lihongjie0209  
       2018-11-03 15:25:57 +08:00
    @fzleee 进程和线程变量有什么关系
    ayang23
        24
    ayang23  
       2018-11-03 16:01:58 +08:00
    简单的回答:不能。
    服务器上跑 Django 一般都是多进程,维护一个可写的全局变量是不可能实现的,用 red is 吧。
    xiaqi
        25
    xiaqi  
       2018-11-03 16:29:08 +08:00 via Android
    只有我一个人觉得,他想把句柄存 redis 这种想法是不对嘛?
    他遇到的真正问题应该是,python 在多进程里面获取到其他进程的句柄吧?如果是这样,把进程 id 存到 redis 里,然后其他进程 id 来获取进程句柄,这样不是 ok 嘛?
    largecat
        26
    largecat  
       2018-11-03 16:48:25 +08:00 via Android
    @ayang23 可以
    在 setting
    lanqing
        27
    lanqing  
    OP
       2018-11-05 10:01:01 +08:00
    非常感谢,已经实现
    @lolizeppelin
    xpresslink
        28
    xpresslink  
       2018-11-05 10:14:18 +08:00
    @lolizeppelin python 的 web 应用都需要用 uwsgi 或 gunicorn 之类的多进程服务器,进程之间的全局变量实际上是相互隔离的。所有只能用 redis 或 django 的 cache 这种公共存储。
    xpresslink
        29
    xpresslink  
       2018-11-05 10:21:24 +08:00
    最省事是用 Django 的缓存

    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    'LOCATION': 'global-variables'
    }
    }

    >>> from django.core.cache import cache
    >>> cache.set('my_key', 'hello, world!', 30)
    >>> cache.get('my_key')
    'hello, world!'
    lanqing
        30
    lanqing  
    OP
       2018-11-05 11:32:33 +08:00
    @xpresslink 试过了,这样的保存不了 socket 对象哦,只能保存一些 dict list 之类的
    yuoboo
        31
    yuoboo  
       2018-11-08 13:00:08 +08:00 via Android
    为什么没有人说存到 session 中呢,那我说一个 session, 或者 cookie
    piaochen0
        32
    piaochen0  
       2019-08-28 16:05:40 +08:00
    @lanqing 麻烦问下楼主最终是怎么解决这个问题的?是用单例的模式?单例模式不是在 uwsgi 或 gunicorn 的多进程实例间不能共享的吗?麻烦赐教。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1038 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:31 · PVG 06:31 · LAX 14:31 · JFK 17:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.