如题,在自己开发 library
目前希望做到的一个效果是,比如
class configure:
def __init__(self):
param1_set = {'person_number':12}
param2_set = {'age': 1}
如果我生成一个 configure 对象用来对库的行为进行控制,我不希望用户可以随意修改其中的数值,我希望将可修改的范围完全限制在我初始化规定的范围里。
众所周知用__slots__可以限制属性不能超出范围 但是像我这样属性内部放的是字典对象,字典的键值对还是可以随意修改的,可能导致各种未知问题 有什么解决办法吗?
1
Livid MOD PRO |
2
monsterxx03 2020 年 2 月 8 日 via iPhone
写个 class 继承 dict,重载__setitem__,直接抛异常
|
3
ipwx 2020 年 2 月 8 日 via Android
dataclass frozen=true?
|
4
metamask 2020 年 2 月 8 日
可以考虑写个
继承 dict, 复写 __setitem__ |
5
metamask 2020 年 2 月 8 日
|
6
imn1 2020 年 2 月 8 日
标题是键,正文是值,那么究竟修改 value 还是 key ?
value 的话,可以 forzendict,或者直接用 pickle 二进制保存 key 的话,可以预置一个固定 key 的 dict,然后从输入更新 value,舍弃非预置的 key |
7
Leigg 2020 年 2 月 8 日 via Android
多了解一下双下划线开头的方法
|
8
est 2020 年 2 月 8 日
namedtuple 香~
|
9
ClericPy 2020 年 2 月 8 日
0. https://www.dogedoge.com/results?q=Python+immutable+dict
1. 用户只要想改, 动态语言基本上用点成本都能改改 2. 主流的保护方式是双下划线保护基类, 子类改起来就很麻烦 3. 可以用一些 immutable 对象做属性调用, 比如基于数组的 namedtuple, 当然 frozendict 和 immutables 这俩库也可以, 就是有点多余了 4. 感觉有点杞人忧天过早优化了, 实在不行, 自己继承个 dict 在 __setitems__ 里面加上一个 warning 就够了 |
11
laike9m 2020 年 2 月 8 日
@Livid 感觉 types.MappingProxyType 应该是正解了,虽然还是只能期待用户不会直接改包含在其中的 dict
@monsterxx03 这个比你想的要 tricky: https://stackoverflow.com/q/2060972/2142577 |
12
frostming 2020 年 2 月 8 日
@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 要更好一点 |
13
aguesuka 2020 年 2 月 8 日
不要暴露字典接口,而是自己提供一个方法比较好吧
|
14
black11black OP |
15
laike9m 2020 年 2 月 9 日
@frostming types.MappingProxyType 实际上就是 abc.Mapping,没什么区别的,还更方便
https://github.com/python/cpython/blob/3.8/Lib/_collections_abc.py#L691 |
16
metamask 2020 年 2 月 9 日
class FrozenDict(dict):
def __setitem__(self, key, value): raise TypeError("'FrozenDict' object does not support item assignment") frozen_dict = FrozenDict 你要的是这样? |
17
metamask 2020 年 2 月 9 日
不过看了你发的这几个贴。。。实际上搞个 tuplename 就算了,
|
19
RRRoger 2020 年 2 月 10 日
frozen dict
|
20
cassidyhere 2020 年 2 月 10 日
可以参考 werkzeug.datastructures 里实现的 ImmutableDict
flask 就用到了 class Flask(_PackageBoundObject): ... default_config = ImmutableDict({"ENV": None, ...}) |