Decorator Syntax For Recursive Properties

J

Jeffrey Froman

Consider the following class:

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

def _ancestors(self, ants=None):
if ants is None:
ants = []
else:
ants.insert(0, self.name)
if self.parent is None:
return ants
return self.parent._ancestors(ants)
ancestors = property(_ancestors)

The ancestor property generates a list ancestor nodes by having each parent
examine its own name recursively. The recursion is managed by calling the
method underlying the parent property, rather than calling the property
directly.

Is it possible to rewrite this property using decorator syntax? Does the
@property decorator create some underlying method that I can call directly?

Alternately, perhaps there is a way to rewrite the recursion so that such a
call is unnecessary? Note that the property should not add its own name if
it is the originating node (the node trying to find _its_ ancestors). So
something like this didn't work for me:

@property
def ancestors(self):
if self.parent is None:
return [self.name]
return [self.name] + self.parent.ancestors

In other words, since there is no longer a list passing from child to parent
during the recursion, is there a graceful way to examine the state of the
ancestor list so far?


Thanks,
Jeffrey
 
P

Peter Otten

Jeffrey said:
it is the originating node (the node trying to find its ancestors). So
something like this didn't work for me:

@property
def ancestors(self):
if self.parent is None:
return [self.name]
return [self.name] + self.parent.ancestors

But this will, I suppose:

@property
def ancestors(self):
if self.parent:
return self.parent.ancestors + [self.parent]
return []

A non-recursive variant:

@property
def ancestors(self):
result = []
node = self.parent
while node:
result.append(node)
node = node.parent
result.reverse()
return result

Peter
 
J

Jeffrey Froman

But this will, I suppose:

@property
def ancestors(self):
if self.parent:
return self.parent.ancestors + [self.parent]
return []

A non-recursive variant:

@property
def ancestors(self):
result = []
node = self.parent
while node:
result.append(node)
node = node.parent
result.reverse()
return result

Indeed, both of these patterns suit my needs. Thanks very much for the
eye-opening insights.

Jeffrey
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top