Python 有办法限制字典不能添加新键吗 ? - 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
black11black

Python 有办法限制字典不能添加新键吗 ?

  •  
  •   black11black Feb 8, 2020 4538 views
    This topic created in 2286 days ago, the information mentioned may be changed or developed.

    如题,在自己开发 library

    目前希望做到的一个效果是,比如

    class configure: def __init__(self): param1_set = {'person_number':12} param2_set = {'age': 1} 

    如果我生成一个 configure 对象用来对库的行为进行控制,我不希望用户可以随意修改其中的数值,我希望将可修改的范围完全限制在我初始化规定的范围里。

    众所周知用__slots__可以限制属性不能超出范围 但是像我这样属性内部放的是字典对象,字典的键值对还是可以随意修改的,可能导致各种未知问题 有什么解决办法吗?

    20 replies    2020-02-10 10:16:29 +08:00
    Livid
        1
    Livid  
    MOD
    PRO
       Feb 8, 2020
    这里有一些实现可以参考:

    https://www.python.org/dev/peps/pep-0416/
    monsterxx03
        2
    monsterxx03  
       Feb 8, 2020 via iPhone
    写个 class 继承 dict,重载__setitem__,直接抛异常
    ipwx
        3
    ipwx  
       Feb 8, 2020 via Android
    dataclass frozen=true?
    metamask
        4
    metamask  
       Feb 8, 2020
    可以考虑写个

    继承 dict, 复写 __setitem__
    metamask
        5
    metamask  
       Feb 8, 2020
    https://github.com/slezica/python-frozendict

    也有这样的库,可以参考下实现
    imn1
        6
    imn1  
       Feb 8, 2020
    标题是键,正文是值,那么究竟修改 value 还是 key ?
    value 的话,可以 forzendict,或者直接用 pickle 二进制保存
    key 的话,可以预置一个固定 key 的 dict,然后从输入更新 value,舍弃非预置的 key
    Leigg
        7
    Leigg  
       Feb 8, 2020 via Android
    多了解一下双下划线开头的方法
    est
        8
    est  
       Feb 8, 2020
    namedtuple 香~
    ClericPy
        9
    ClericPy  
       Feb 8, 2020
    0. https://www.dogedoge.com/results?q=Python+immutable+dict
    1. 用户只要想改, 动态语言基本上用点成本都能改改
    2. 主流的保护方式是双下划线保护基类, 子类改起来就很麻烦
    3. 可以用一些 immutable 对象做属性调用, 比如基于数组的 namedtuple, 当然 frozendict 和 immutables 这俩库也可以, 就是有点多余了
    4. 感觉有点杞人忧天过早优化了, 实在不行, 自己继承个 dict 在 __setitems__ 里面加上一个 warning 就够了
    laike9m
        10
    laike9m  
       Feb 8, 2020
    @Livid 感觉 types.MappingProxyType 应该是正解了,虽然还是只能期待用户不会直接改包含在其中的 dict
    laike9m
        11
    laike9m  
       Feb 8, 2020
    @Livid 感觉 types.MappingProxyType 应该是正解了,虽然还是只能期待用户不会直接改包含在其中的 dict
    @monsterxx03 这个比你想的要 tricky: https://stackoverflow.com/q/2060972/2142577
    frostming
        12
    frostming  
       Feb 8, 2020
    @monsterxx03 直接继承 dict 不是个好方法,(tomlkit 就是这样,我都报过好几个 bug 了) https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/

    @laike9m 用 collections.abc.Mapping 可能比 types.MappingProxyType 要更好一点
    aguesuka
        13
    aguesuka  
       Feb 8, 2020
    不要暴露字典接口,而是自己提供一个方法比较好吧
    black11black
        14
    black11black  
    OP
       Feb 9, 2020
    @freakxx

    试了一下 setitem 是无论新建键值对,还是修改已有条目都会调用的啊,不太满足需求
    想看一下实现部分 py 的源码,这种不用库导入的 bif 找了半天没找到在什么地方。
    laike9m
        15
    laike9m  
       Feb 9, 2020
    @frostming types.MappingProxyType 实际上就是 abc.Mapping,没什么区别的,还更方便
    https://github.com/python/cpython/blob/3.8/Lib/_collections_abc.py#L691
    metamask
        16
    metamask  
       Feb 9, 2020
    class FrozenDict(dict):
    def __setitem__(self, key, value):
    raise TypeError("'FrozenDict' object does not support item assignment")


    frozen_dict = FrozenDict


    你要的是这样?
    metamask
        17
    metamask  
       Feb 9, 2020
    不过看了你发的这几个贴。。。实际上搞个 tuplename 就算了,
    frostming
        18
    frostming  
       Feb 9, 2020
    @laike9m 抽象类和具体类的区别
    RRRoger
        19
    RRRoger  
       Feb 10, 2020
    frozen dict
    cassidyhere
        20
    cassidyhere  
       Feb 10, 2020
    可以参考 werkzeug.datastructures 里实现的 ImmutableDict
    flask 就用到了
    class Flask(_PackageBoundObject):
    ...
    default_cOnfig= ImmutableDict({"ENV": None, ...})
    About     Help     Advertise     Blog     API     FAQ     Solana     3240 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 102ms UTC 13:52 PVG 21:52 LAX 06:52 JFK 09:52
    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