POPON OOP and Lists

I am new to Python and it is OOP and I cannot get it to work. Here is my code:

class Tree: root = None; data = []; def __init__(self, equation): self.root = equation; def appendLeft(self, data): self.data.insert(0, data); def appendRight(self, data): self.data.append(data); def calculateLeft(self): result = []; for item in (self.getLeft()): if (type(item) == type(self)): data = item.calculateLeft(); else: data = item; result.append(item); return result; def getLeft(self): return self.data; def getRight(self): data = self.data; data.reverse(); return data; tree2 = Tree("*"); tree2.appendRight(44); tree2.appendLeft(20); tree = Tree("+"); tree.appendRight(4); tree.appendLeft(10); tree.appendLeft(tree2); print(tree.calculateLeft()); 

Does it look like tree2 and tree share the "data" of the list?

At the moment, I would like it to output something like [[20,44], 10, 4], but when I

 tree.appendLeft(tree2) 

I get RuntimeError: maximum recursion depth exceeded , and when I will not even appendLeft(tree2) , it will output [10, 20, 44, 4] (!!!). What am I missing here? I am using Portable Python 3.0.1.

thanks

+4
source share
3 answers

The problem is that you declared data as a class variable, so all instances of the class have the same list. Instead, put self.data = [] in your __init__ .

Also get rid of all these semicolons. They are not needed and clutter up your code.

+9
source

Move the root and data to the __init__ definition. Be that as it may, you have defined them as class attributes. This makes them available to all instances of the Tree class. When you create two trees ( tree and tree2 ), they both use the same list, which are accessed using self.data . For each instance to have its own instance attribute, you must move the declaration to the __init__ function.

 def __init__(self, equation): self.root = equation self.data = [] 

Also use

  if isinstance(item,Tree): # This is True if item is a subclass of Tree 

instead

  if (type(item) == type(self)): # This is False if item is a subclass of Tree 

and change

 data = self.data 

to

 data = self.data[:] 

in getRight . When you say data = self.data , then the variable name data points to the same list that self.data points self.data . When you subsequently flip data , you will also cancel self.data . To undo only data , you must copy the list. self.data[:] uses cutting notation to return a copy of the list. Note that self.data elements can be tree s, and self.data and self.data[:] can contain the same elements. I don't think your code requires these elements to be copied, but you will need to copy self.data recursively, if so.

 def getRight(self): data = self.data[:] data.reverse() return data 
+4
source

When you define attributes as follows:

 class Tree: root = None data = [] 

.. this empty list object is created because Python defines the class, not when you create a new instance. This is a class attribute, not an instance attribute. The value of Tree.root is the same object in all cases:

 class Tree: root = None data = [] t1 = Tree() t2 = Tree() print id(t1.data) == id(t2.data) # is True, they are the same object 

To get the expected behavior, move the creation of an empty list to the __init__ function, which is called only when a new instance is created and only modifies this instance (since it assigns self ):

 class Tree: def __init__(self): self.root = None self.data = [] t1 = Tree() t2 = Tree() print id(t1.data) == id(t2.data) # False, they are different objects 

This question explains why this behavior might be helpful.

+3
source

All Articles