gpt4 book ai didi

python - 如何将可变属性作为​​不可变对象(immutable对象)返回?

转载 作者:太空宇宙 更新时间:2023-11-03 18:36:46 25 4
gpt4 key购买 nike

有没有办法返回可变属性但保护它免受更新?

我有一个 Calendar 类,它使用内部 dict 实例将 datetime.date 实例映射到 list 实例事件标识符的数量:

class Calendar:

def __init__(self):
self._dict = {}

def add_event(self, date, event):
if date in self._dict:
self._dict[date].append(event.id)
else:
self._dict[date] = [event.id]

def get_event_ids(self, date):
if date in self._dict:
return self._dict[date]
else:
return []

我想保护日历免受这些更新的影响:

calendar = Calendar()
calendar.add_event(date, event)
event_ids = calendar.get_event_ids(date)
event_ids[0] = 42 # updates the mutable list in the calendar

理由是用户可能想要更新日历返回的事件标识符列表,但他不希望这样做会更新日历。

只读属性不会阻止用户更新列表。

解决方案似乎返回列表的副本。但是:

  1. list 实例可能会变得很大,并且 Calendar.get_event_ids 函数可能会被多次调用,因此每次调用时执行复制可能会变得低效。
  2. 如果用户确实想要更改日历,则返回副本会误导他认为他可以更改,因为更新 list 实例不会引发异常。
  3. 我认为,如果需要的话,用户应该决定是否制作副本。
  4. 我想知道是否还有其他方法可以实现同样的目标。

另一种可能性是返回我自己的 ImmutableList 类的实例。它解决了 2 和 3,但不能解决 1(因为我必须复制 list 实例来初始化 ImmutableList 实例),也不能解决 4。此外,对于一个非常简单的问题。

我还知道“我们都是同意的成年人”,并且过度保护我的实例属性并不是 Python 风格。但我认为我的好奇心战胜了我。

最佳答案

这是一种创建不可变列表的方法,可以解决您的所有问题:

import collections.abc


class ImmutableList(collections.abc.Sequence):

def __init__(self):
self._list = []

def __getitem__(self, index):
return self._list[index]

def __len__(self):
return len(self._list)


class Calendar:

def __init__(self):
self._dict = collections.defaultdict(ImmutableList)

def add_event(self, date, event):
self._dict[date]._list.append(event.id)

def get_event_ids(self, date):
return self._dict[date]

ImmutableList 公开了一个类似元组的 API,因此用户不会意外更改某些内容,但具有一个私有(private) _list 属性,Calendar 可以使用该属性访问操作数据。请注意,前导下划线只是一种约定,实际上并不像 C++ 等语言那样强制执行私有(private)作用域。 Here这个问题可以更好地解释范围。

关于python - 如何将可变属性作为​​不可变对象(immutable对象)返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21424126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com