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