尽信书不如无书,从一道 Python 单例面试题想到的 - V2EX
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
mengzhuo
V2EX    Python

尽信书不如无书,从一道 Python 单例面试题想到的

  •  
  •   mengzhuo 2015-06-08 14:58:26 +08:00 4810 次点击
    这是一个创建于 3783 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在网上看到一道基本面试题:
    Python单例如何实现?

    所谓的标准答案里,有用元编程(metaclass)的,有用decorator cache的
    但我觉得这些都不如module cache来得快,也不如module cache简单优雅,上面的方法都是故作玄虚。
    下面就有说效率比module cache来得快!
    我现在就告诉大家,那些网上的,所谓的标准答案至少慢100%,压根不如最简单的方法,证据在此,
    第 1 条附言    2015-06-08 17:33:01 +08:00
    15 条回复    2015-08-06 11:04:51 +08:00
    wohenyingyu01
        1
    wohenyingyu01  
       2015-06-08 15:19:29 +08:00
    下面呢?
    nooper
        2
    nooper  
       2015-06-08 15:24:32 +08:00
    单例模式在多进程下呢?
    est
        3
    est   div class="badges">   2015-06-08 15:32:12 +08:00
    m = ModuleSingleton()


    这货不就是全局变量?

    多进程考虑单例模式,直接反问主考官星际网络30%掉包 1500ms 延迟下集群如何实现单例。
    mengzhuo
        4
    mengzhuo  
    OP
       2015-06-08 15:52:46 +08:00
    @est

    如果你在其他模块里import进来就不是了

    只是为了说明metaclass decorator cache都是不必要的花式动作
    ibigbug
        5
    ibigbug  
       2015-06-08 16:34:42 +08:00
    ModuleSingleton 跟其他两个不一样吧。这个是事先生成好了一个放在那里等人来用。
    binux
        6
    binux  
       2015-06-08 16:44:46 +08:00   1
    第一次听说创建个全局变量就叫单例的。
    如果这个单例我实际上不用呢?你也要创建吗?
    Smartype
        7
    Smartype  
       2015-06-08 17:19:30 +08:00 via iPhone
    1. 这就是 singleton???
    2. 这样就快?
    哪位给解释下
    mengzhuo
        8
    mengzhuo  
    OP
       2015-06-08 17:30:13 +08:00
    @binux
    @Smartype
    你们都不看下面那个gist是怎么用的么!!创建的是module级的对象!!
    真要深追的话,哪个单例不是跟着对象的“全局变量”?

    快100%不算快么
    hahastudio
        9
    hahastudio  
       2015-06-08 17:36:45 +08:00
    全局变量就算单例我也就不提了,用 Module 算是一个讨巧的方法
    但是你只能庆幸你的 Python 实现是带 GIL 的,如果是不带 GIL 的= =
    dddd     10
    dddd  
       2015-06-08 17:38:54 +08:00   1
    这是我们 Java 设计模式课上老师所讲的翻版: http://damnever.github.io/2015/04/07/singleton-pattern-in-python/
    JQ
        11
    JQ  
       2015-06-08 17:51:00 +08:00
    以前都没有关注到这个
    Smartype
        12
    Smartype  
       2015-06-08 20:19:28 +08:00
    @dddd @hahastudio 对啊,double check才对嘛,我觉得楼主不知道我要说什么,好在python有GIL,也是可以的,哈哈
    ming2281
        13
    ming2281  
       2015-06-08 20:33:12 +08:00
    缓存一个URL在模块级别,题主是这样写的吗?

    ```
    _URL = xxx
    def get(refresh=False):
    if refresh:
    get.reates = {}
    if get.retes:
    return get.rates

    with urllib.request.urlopen(_URL) as f:
    for line in f:
    line = line.rstrip().decode('utf-8')
    if not line or line.startswith(("#", "Date")):
    continue
    name, currency,*rest = re.split(r"\s*,\s*, line)
    key = "{}{})".format(name, currency)
    try:
    get.rates[key] = float(rest[-1])
    except ValueError as err:
    print "error:{}: {}".format(err, line)
    return get.rates
    get.rates = {}
    ```
    est
        14
    est  
       2015-06-09 12:24:30 +08:00
    还是ruby简单。直接 ||= 就行了。
    aec4d
        15
    aec4d  
       2015-08-06 11:04:51 +08:00
    题主啊,你应该先别谈效率。。。先写对了再说。。。
    你这里至少要加一个@classmethod 这样就是一个正确的单例了。再根据6楼说的在调用的时候在创建。那么可以考虑这样写
    class ModuleSingleton(object):

    @classmethod
    def get(cls):
    if not hasattr(cls, '_instance'):
    cls._instance = 0
    cls._instance += 1
    return cls._instance


    a = ModuleSingleton()
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5312 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 01:15 PVG 09:15 LAX 18:15 JFK 21:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86