对象池,保留对池的引用,使非法状态不可表示。

huangapple go评论45阅读模式
英文:

Pool objects, keep reference to pool, make illegal states irrepresentable

问题

我有一些对象,我想要"池化"它们,即将它们放入列表或集合中,使得:

  • 每个对象最多出现在一个列表中,以及
  • 每个对象知道它属于哪个列表。

在Python中,我可以这样做:

# 创建对象

pool1 = [obj1, obj5, obj6]
pool2 = [obj3]
pool3 = [obj8, obj7]

obj1.pool = pool1
obj2.pool = None
obj3.pool = pool2
obj4.pool = None
obj5.pool = pool1
obj6.pool = pool1
obj7.pool = pool3
obj8.pool = pool3

这可以工作,但有一个缺点,即数据结构可以表示不合法的状态,例如:

pool1 = [obj1]
pool2 = []

obj1.pool = pool2

pool1 = [obj1]
pool2 = [obj1]

obj1.pool = pool1

是否有更适合的数据结构用于此目的?

英文:

I have a number of objects and I'd like to "pool" them, i.e., put them into lists or sets such that

  • every object appears in at most one list, and
  • every object knows which list it's in.

In Python, I could do

# create objects

pool1 = [obj1, obj5, obj6]
pool2 = [obj3]
pool3 = [obj8, obj7]

obj1.pool = pool1
obj2.pool = None
obj3.pool = pool2
obj4.pool = None
obj5.pool = pool1
obj6.pool = pool1
obj7.pool = pool3
obj8.pool = pool3

This works, but has the disadvantage that the data structure can represent illegal states, e.g.,

pool1 = [obj1]
pool2 = []

obj1.pool = pool2

or

pool1 = [obj1]
pool2 = [obj1]

obj1.pool = pool1

Is there a more fitting data structure for this?

答案1

得分: 1

以下是翻译好的部分:

"I don't think there is a more fitting data structure for this, as you need the association to work in two directions (from object to list, from list to object)."
"我认为没有比这更适合的数据结构,因为你需要使关联在两个方向上工作(从对象到列表,从列表到对象)。"

"The best is probably to encapsulate this logic in a class and require that the caller uses only the provided methods to manipulate the data structure."
"最好的方法可能是将这个逻辑封装在一个类中,并要求调用者只使用提供的方法来操作数据结构。"

"In Python that could look like this:"
"在Python中,可以如下所示:"

"class Node:"
"class Node:"
"def init(self, name):"
"def init(self, name):"
"self.name = name"
"self.name = name"
"self.pool = None"
"self.pool = None"

"def repr(self):"
"def repr(self):"
"return self.name"
"return self.name"

"class Pools():"
"class Pools:"
"def init(self):"
"def init(self):"
"self._pools = {}"
"self._pools = {}"

"def assign(self, poolid, obj):"
"def assign(self, poolid, obj):"
"if poolid not in self._pools:"
"if poolid not in self._pools:"
"self._pools[poolid] = set()"
"self._pools[poolid] = set()"
"if obj.pool is not None:"
"if obj.pool is not None:"
"self._pools[obj.pool].discard(obj)"
"self._pools[obj.pool].discard(obj)"
"if poolid is not None:"
"if poolid is not None:"
"self._pools[poolid].add(obj)"
"self._pools[poolid].add(obj)"
"obj.pool = poolid"
"obj.pool = poolid"

"def unassign(self, obj):"
"def unassign(self, obj):"
"self.assign(None, obj)"
"self.assign(None, obj"

"def content(self, poolid):"
"def content(self, poolid):"
"return list(self._pools[poolid])"
"return list(self._pools[poolid])"

"# demo"
"# 演示"
"a = Node("a")"
"a = Node('a')"
"b = Node("b")"
"b = Node('b')"
"c = Node("c")"
"c = Node('c')"

"pools = Pools()"
"pools = Pools()"
"pools.assign(0, a)"
"pools.assign(0, a)"
"pools.assign(0, b)"
"pools.assign(0, b)"
"pools.assign(5, c)"
"pools.assign(5, c)"
"pools.assign(3, a)"
"pools.assign(3, a)"
"pools.assign(3, c)"
"pools.assign(3, c)"
"pools.unassign(b)"
"pools.unassign(b)"

"print(pools.content(0)) # []"
"print(pools.content(0)) # []"
"print(pools.content(3)) # ['a', 'c']"
"print(pools.content(3)) # ['a', 'c']"
"print(pools.content(5)) # []"
"print(pools.content(5)) # []"
"print(a.pool) # 3"
"print(a.pool) # 3"
"print(b.pool) # None"
"print(b.pool) # None"
"print(c.pool) # 3"
"print(c.pool) # 3"

"You could improve on this and make Pools a subclass of dict, but you get the idea."
"你可以改进这个并将Pools作为dict的子类,但你明白了这个思路。"

英文:

I don't think there is a more fitting data structure for this, as you need the association to work in two directions (from object to list, from list to object).

The best is probably to encapsulate this logic in a class and require that the caller uses only the provided methods to manipulate the data structure.

In Python that could look like this:

class Node:
    def __init__(self, name):
        self.name = name
        self.pool = None

    def __repr__(self):
        return self.name
    
class Pools():
    def __init__(self):
        self._pools = {}

    def assign(self, poolid, obj):
        if poolid not in self._pools:
            self._pools[poolid] = set()
        if obj.pool is not None:
            self._pools[obj.pool].discard(obj)
        if poolid is not None:
            self._pools[poolid].add(obj)
        obj.pool = poolid

    def unassign(self, obj):
        self.assign(None, obj)
        
    def content(self, poolid):
        return list(self._pools[poolid])


# demo
a = Node("a")
b = Node("b")
c = Node("c")

pools = Pools()
pools.assign(0, a)
pools.assign(0, b)
pools.assign(5, c)
pools.assign(3, a)
pools.assign(3, c)
pools.unassign(b)

print(pools.content(0))  # []
print(pools.content(3))  # ['a', 'c']
print(pools.content(5))  # []
print(a.pool) # 3
print(b.pool) # None
print(c.pool) # 3

You could improve on this and make Pools a subclass of dict, but you get the idea.

huangapple
  • 本文由 发表于 2023年2月6日 06:29:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定