1

The following are my class definitions :

class logline:
    def __init__(self,t,cmp,msg):
        self.t = t
        self.cmp = cmp
        self.msg = msg

class cluster:
    clusters = []
    def __init__(self,status,log):
        self.status = status
        self.children = []
        self.eventlogs = []
        self.rep_msg = log.msg
        self.addLog(log)
        self.prev = None
        if(status == 'root'):
            cluster.clusters.append(self)            
    def prev(self):
        return self.prev
    def print_children(self): 
        for child in range(0,len(self.children)):
            print(self.children[child].rep_msg)
            self.children[child].print_logs()
    def print_logs(self):
        for log in self.eventlogs:
                print(log.msg)
    def add_child(self,status,log):
        temp = cluster(status,log)
        self.children.append(temp)
        temp.prev=self
        return temp
    def addLog(self,log):
        self.eventlogs.append(log)

Now, tree is my root cluster node

tree = cluster('root',log1)

and prev is my child cluster node added to tree

tree = tree.add_child('child',log6)

When I try: tree = tree.prev() I should get back tree, but it gives me the error:

tree = tree.prev()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'cluster' object is not callable

On the other hand : callable(cluster) evaluates to true

my class definitions are based off of: How can I implement a tree in Python? Are there any built in data structures in Python like in Java?

I've searched around but can't seem to find anything which matches my situation

Thanks in advance

Edit : So, I am an absolute beginner in python, I should have probably led with that

>>> print(tree)
<__main__.cluster object at 0x02AF8590>
>>> print(tree.prev)
<__main__.cluster object at 0x02AEA270>

I'm assuming since I'm getting different locations for both statements, prev has been set to something But I'm not able to go back to my parent node with
return self.prev

Community
  • 1
  • 1
K. Singh
  • 115
  • 7
  • 1
    BTW, you code would be easier to read if you put a blank line after each method definition. Also, you should use the [PEP-0008](https://www.python.org/dev/peps/pep-0008/) naming conventions and give your classes CamelCase names, eg `Cluster` and `Logline` or `LogLine`. – PM 2Ring Feb 15 '17 at 08:47

2 Answers2

1

The cluster class itself is callable: when you call it it returns an instance of the class. However, an instance of the class isn't callable. But (you may ask) why is your code even trying to call an instance of the class?

Well, that's because the .add_child method returns the new temp instance, but it sets the temp.prev attribute to self, the parent instance. And that overrides the .prev method of that instance. So when you do tree.prev() it's trying to call that parent instance instead of the prev method.

Incidentally, the cluster.__init__ method also replaces the .prev method with None.

So you need to get rid of that name clash. I suggest you rename the attribute to ._prev.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
0

prev is an attribute of your cluster instance tree (overriding the method of the same name).

cluster's constructor __init__ is what makes the cluster class callable. But when you instantiate the cluster class using __init__ you get an instance. This instance is not callable, unless you implement a __call__ method in your class.

To check this:

callable(cluster) #Returns True
callable(tree) #Returns False
M.T
  • 4,917
  • 4
  • 33
  • 52