How to set a class attribute a specified number of times in Python
<p>Suppose we have a class <code>Node</code> which is initialized as follows:</p>

<pre><code>class Node(object):
    def __init__(self, data=None, next_node=None, prev_node = None):
        self.data = data
        self.next = next_node
        self.prev = prev_node
</code></pre>

<p>and we create an instance <code>head</code> as follows:</p>

<pre><code>head = Node(data=4)
head.next = Node(data=5)
head.next.next = Node(data=6)
head.prev = Node(data=2)
</code></pre>

<p>I'd like to add another node to the doubly-linked list, which I could do by</p>

<pre><code>head.next.next.next = Node(data=8)
</code></pre>

<p>However, instead of writing ".next" three times, I would like to use a method which takes as input the number of times to call ".next" - that is, something like <code>head.next_n_times(3) = Node(data=8)</code> which would have the same effect. How could I achieve this?</p>

<p>Here is what I've tried so far:</p>

<pre><code>class Node(object):
    def __init__(self, data=None, next_node=None, prev_node = None):
        self.data = data
        self.next = next_node
        self.prev = prev_node

    def next_n_times(self, n):
        next_node = self.next
        for i in range(n-1):
            next_node = next_node.next
        return next_node

head = Node(data=4)
head.next = Node(data=5)
head.next.next = Node(data=6)
head.prev = Node(data=2)
data = 5

head.next_n_times(3) = Node(data=8)
</code></pre>

<p>However, I get the error message</p>

<pre><code>File "sorted_insert_scratch.py", line 19
    head.next_n_times(5) = Node(data=8)
SyntaxError: can't assign to function call
</code></pre>

<p>It seems like the <code>next_n_times</code> method works as a 'getter', but not as a 'setter'. How can I make it work as a 'setter'?</p>

<blockquote>
  <p>It seems like the next_n_times method works as a 'getter', but not as a 'setter'. How can I make it work as a 'setter'?</p>
</blockquote>

<p>What you get back is a <code>Node</code> object, and you want to set its <code>next</code> attribute: </p>

<pre><code>head.next_n_times(3).next = Node(data=8)
</code></pre>

<p>To do what you want you have to change the syntax:</p>

<pre><code>def append_at_next_n(self, n, node):
    next_node = self.next
    for i in range(n-1):
        next_node = next_node.next
    next_node.next = node
    return next_node
</code></pre>

<p>To make it work in your example:</p>

<pre><code>head.append_at_next_n(3, Node(data=8))
</code></pre>

<p>Note that <code>head.next.next.next</code> is currently <code>None</code>, as you only set <code>head.next.next</code>, so the above will raise an exception unless you add another node first.</p>

<p>Expanding on this, however, you could make it kind of work with an actual property setter:</p>

<pre><code>@property
def appender(self):
    return self

@appender.setter
def append_at_next_n(self, args):
    n, node = args
    next_node = self.next
    for i in range(n-1):
        next_node = next_node.next
    next_node.next = node
    return next_node

head.appender = (3, Node(2))
</code></pre>

<p>It doesn't help readability though.</p>

python