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
saximi
V2EX  ›  Python

请教一个关于__missing__方法的问题

  •  
  •   saximi · 2017-10-23 19:18:42 +08:00 · 3344 次点击
    这是一个创建于 2593 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在网上看到这么一道问题。当给定以下字典的子类,下面的代码能运行么,为什么? 
    class D(dict): 
            def __missing__(self,key): 
                    return[] 
    
    d=D() 
    d['f']=12 
    
    
    网上给出的答案是可以运行,因为当 key 缺失时,执行 DefaultDict 类,字典的实例将自动实例化这个数列。 
    但是,我自己试着下了下面的代码,结果发现也能运行,所以不是很理解上面答案想说明什么,以及上面这道题目想考察的点是什么?恳请大家指点,感谢 
    
    class E(dict): 
            pass 
    
    e=E() 
    e['f']=13 
    
    9 条回复    2017-10-24 20:17:06 +08:00
    jmc891205
        1
    jmc891205  
       2017-10-23 20:25:11 +08:00
    不知道它想考察什么
    只有从字典里取值的时候才会有 key 缺失的情况。。。
    n329291362
        2
    n329291362  
       2017-10-23 20:25:37 +08:00
    ??
    d['f']=12 难道不是赋值吗
    n329291362
        3
    n329291362  
       2017-10-23 20:28:01 +08:00
    你直接 打印 e['f'] 就会报错了 d['f']的话会显示 []
    flaneurse
        4
    flaneurse  
       2017-10-23 21:01:27 +08:00
    有时候为了方便起见,就算某个键在映射里不存在,希望在通过这个键读取值的时候能得到一个默认值。有两个途径能帮我们达到这个目的,一个是通过 defaultdict,另一个是给自己定义一个 dict 的子类,然后在子类中实现__missing__ 方法。
    saximi
        5
    saximi  
    OP
       2017-10-23 21:50:13 +08:00
    @n329291362
    @flaneurse 非常感谢!
    zhusimaji
        6
    zhusimaji  
       2017-10-23 23:32:42 +08:00 via iPhone
    楼主有兴趣可以深究一下 missing 在哪调用? get 方法也可以获取值,但是为啥不同于 getitem 函数?四楼基本上解决了楼主的问题
    hcnhcn012
        7
    hcnhcn012  
       2017-10-24 00:15:52 +08:00 via iPhone
    https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
    文档里讲的很清楚啊,你那个是在 dict 中添加东西了,如果光是 e[‘ f ’],因为你没有写__missing__(),所以会抛出一个 keyerror,如果有__missing__(),那就返回或者抛出你在 missing 里写东西啊,其实还有一种简单的方法,就是 get(key[, default]),如果找不到 key 就返回 default,默认是 None。一个简单的字典缓存装饰器就可以用:
    def buffer(fn):
    cache = {}
    miss = object()

    @wraps(fn)
    def wrapper(*args):
    result = cache.get(args, miss)
    if result is miss:
    result = fn(*args)
    cache[args] = result
    return result

    return wrapper
    saximi
        8
    saximi  
    OP
       2017-10-24 20:11:23 +08:00
    @zhusimaji 谢谢指点,我专门去查了__missing__、__get__和__getitem__的说明,涨知识了!
    saximi
        9
    saximi  
    OP
       2017-10-24 20:17:06 +08:00
    @hcnhcn012 谢谢指点!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1033 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 21:37 · PVG 05:37 · LAX 13:37 · JFK 16:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.