【问题标题】:linked list method vs functions链表方法与函数
【发布时间】:2018-11-16 02:37:03
【问题描述】:

我试图理解为什么一个函数可以作为外部函数工作,但如果我将它作为方法移到类中就无法工作。

很快我就创建了一个链表类:

class Link:
    """A linked list."""
    empty = ()

    def __init__(self, first, rest=empty):
        assert rest is Link.empty or isinstance(rest, Link)
        self.first = first
        self.rest = rest

    def __str__(self):
        string = '<'
        while self.rest is not Link.empty:
            string += str(self.first) + ', '
            self = self.rest
        return string + str(self.first) + '>'

所以当我尝试创建一个名为stretch的函数时,我可以:

def stretch(s, repeat=0):
    """Replicate the kth element k times, for all k in s."""
    if s is not Link.empty:
        stretch(s.rest, repeat+1)
        for i in range(repeat):
            s.rest = Link(s.first, s.rest)

成功了:

a = Link(3, Link(4, Link(5, Link(6))))
print(a)  # >>> <3, 4, 5, 6>
stretch(a)
print(a)  # >>> <3, 4, 4, 5, 5, 5, 6, 6, 6, 6>

但是,当我尝试将此函数创建为类方法时:

def stretch(self, repeat=0):
    """Replicate the kth element k times, for all k in a linked list."""
    if self is not Link.empty:
        self.rest.stretch(repeat+1)
        for i in range(repeat):
            self.rest = Link(self.first, self.rest) 

现在不行了:

b = Link(3, Link(4, Link(5, Link(6))))
b.stretch()
print(b)
# >>> AttributeError: 'tuple' object has no attribute 'stretch'

我知道当b 到达最后一个元素时,b.rest 将是一个空元组,但在方法中,它说if self is not Link.empty 它不应该执行任何操作。为什么它给我错误信息?

谢谢!

【问题讨论】:

  • 你定义了第二个stretch 类吗?
  • @DYZ 我当然做到了。
  • 问问自己:selfLink的实例,曾经 Link.empty不是实例Link?

标签: python oop linked-list


【解决方案1】:

问题发生在self.rest.stretch(repeat+1) 行。由于Link(3, Link(4, Link(5, Link(6))))中没有将第二个参数传递给构造函数,所以()的默认值用于初始化字段self.rest,此后该字段的值永远不会改变。因此,self.rest.stretch(repeat+1) 实际上是().stretch(repeat+1)。当然()这个空元组没有stretch这个属性。

第一个函数有效,因为它没有违规语句。

【讨论】:

  • 我明白为什么会变成().stretch(n)。但是在该方法中,是不是有一个if 条件来帮助防止在self.rest.stretch 的后半部分执行空元组?
  • 那么我应该如何将这个函数写入类呢?
  • 这不是关于self,而是关于self.rest。你永远不会检查self. rest 是否为空。附带说明一下,您应该使用 None 而不是空元组。
【解决方案2】:

无论传递给stretchsLink 对象还是Link.empty,第一个函数都有效。

第二个成员函数在对象为Link.empty时不起作用,因为Link.empty是一个没有方法的元组。你甚至永远不会让它进入你的if 会捕获它的函数。

您需要在通话前将if 移到外面。

【讨论】:

  • 我明白了。这是有道理的,因为stretch 现在在Class Link 中,所以无论我给出什么if 条件,一个元组都找不到这个方法。非常感谢!
  • @Code_Control_jxie0755 我只是添加了一点解释。
猜你喜欢
  • 2021-03-29
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2021-04-03
  • 2012-05-09
  • 1970-01-01
相关资源
最近更新 更多