合并/变形对象并保留Python中的旧引用

时间:2018-11-09 00:21:19

标签: python algorithm

最近,我正在从事招聘人员的面试任务。任务涉及对属于同一团队的球员进行计数。无需深入研究作业详细信息,我就可以说明问题。

  • 每个球员都有可能发展自己的团队。
  • 这要求每个团队成员都必须有一个共同柜台的参考。
  • 由于有共同的球员,两支球队也有可能合并。在这种情况下,有两个团队和两个公共柜台。
  • 现在合并后,希望两支球队的所有球员都引用同一个计数器。

我知道一种方法是用另一支球队的对方参考资料更新一支球队的球员。但这听起来并不理想。因此,问题

两个如何合并两个通用计数器?

从一般意义上说,如何设计一个可以合并对象的类,这样可以通过现有引用来引用其结果对象?

我什至不知道如何描述我的要求:变形/合并对象?但是我用下面的代码做到了。它是众所周知的设计模式(例如转发)吗? Python中有没有更短的更好的方法?

def morph(func):
    def wrapper(obj, *args):
        morpheus = obj
        _next = getattr(obj, 'morpheus', None)
        while _next:
            morpheus = _next
            _next = getattr(_next, 'morpheus', None)

        return func(morpheus, *args)

    return wrapper


class Counter(object):
    def __init__(self):
        self.count = 0

    @morph
    def incr(self, count=1):
        self.count += count

    @morph
    def morph_it(self, new_counter):
        if not isinstance(new_counter, Counter):
            raise TypeError("Can not morph into an object of different kind.")

        # Get effective object of this counter.
        new_counter = new_counter.get_counter()
        # Check it's not the same object.
        if self is not new_counter:
            new_counter.incr(self.count)
            setattr(self, 'morpheus', new_counter)

    @morph
    def get_count(self):
        return self.count

    @morph
    def get_counter(self):
        return self


class TestCounter(TestCase):
    def test_increment_after_morph(self):
        counter1 = Counter()
        counter2 = Counter()

        for i in range(10):
            counter1.incr()
        # Morph counter2 to counter1
        counter2.morph_it(counter1)
        self.assertEqual(counter1.get_count(), 10)
        self.assertEqual(counter2.get_count(), 10)

        counter1.incr()
        self.assertEqual(counter1.get_count(), 11)
        self.assertEqual(counter2.get_count(), 11)

        counter2.incr()
        self.assertEqual(counter1.get_count(), 12)
        self.assertEqual(counter2.get_count(), 12)

0 个答案:

没有答案