链表方法与函数

时间:2018-11-16 02:37:03

标签: python oop linked-list

我试图理解为什么函数可以用作外部函数,但是如果我将其作为方法移入类,将无法正常工作。

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

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不应执行任何操作。为什么会显示错误消息?

谢谢!

2 个答案:

答案 0 :(得分: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

第一个函数起作用,因为它没有令人反感的语句。

答案 1 :(得分:1)

无论传递给s的{​​{1}}是stretch对象还是Link,第一个函数都起作用。

当对象为Link.empty时,第二个成员函数不起作用,因为Link.empty是一个没有方法的元组。您甚至都无法将其放入Link.empty会捕获它的函数中。

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