【发布时间】:2021-02-03 23:16:21
【问题描述】:
问题
类似于previous questions,我想创建一个冻结/不可变字典。具体来说,初始化后,用户在尝试使用__delitem__ 和__setitem__ 方法时应该得到一个ValueError。
与前面的问题不同,我特别希望它是一个子类,其中初始化类型被限制为特定的键和值类型。
尝试的解决方案
我自己在accomplishing this with collections.UserDict 的尝试失败了:
class WorkflowParams(UserDict):
def __init__(self, __dict: Mapping[str, str]) -> None:
super().__init__(__dict=__dict)
def __setitem__(self, key: str, item: str) -> None:
raise AttributeError("WorkflowParams is immutable.")
def __delitem__(self, key: str) -> None:
raise AttributeError("WorkflowParams is immutable.")
尝试使用时:
workflow_parameters = WorkflowParams(
{
"s3-bucket": "my-big-bucket",
"input-val": "1",
}
)
失败了
Traceback (most recent call last):
File "examples/python_step/python_step.py", line 38, in <module>
workflow_parameters = WorkflowParams(
File "/home/sean/git/scargo/scargo/core.py", line 14, in __init__
super().__init__(__dict=__dict)
File "/home/sean/miniconda3/envs/scargo/lib/python3.8/collections/__init__.py", line 1001, in __init__
self.update(kwargs)
File "/home/sean/miniconda3/envs/scargo/lib/python3.8/_collections_abc.py", line 832, in update
self[key] = other[key]
File "/home/sean/git/scargo/scargo/core.py", line 17, in __setitem__
raise AttributeError("WorkflowParams is immutable.")
AttributeError: WorkflowParams is immutable.
因为how __init__() resolves methods。
不合格的替代品
由于我需要一个子类,commonly suggested solution of using MappingProxyType 不符合我的要求。
此外,我怀疑建议子类化dict 的答案,因为这似乎会导致一些unintended behaviour。
【问题讨论】:
-
好吧,无论你传递给 `super().__init__(__dict=__dict)` 最终都会调用
__setitem__,为什么不直接在__init__中使用 @987654339 手动执行此操作@? -
@juanpa.arrivillaga 不知何故,这也行不通。
super().__setitem__(key, __dict[key])仍然调用我的子类'__setitem__。 -
噢,是的,因为它是一种抽象方法。我的意思是,只需使用
self.data[key] = value -
@juanpa.arrivillaga
self.data不是类属性,所以在调用UserDict.__init()__之前它不存在。 -
我只是尝试调用 super().__setitem__() 作为构造函数的一部分,这一切似乎都按预期工作。你能建议什么 Python 版本似乎不起作用吗?另外你为什么不想调用 UserDict.__init__()?
标签: python python-3.x dictionary data-structures immutability