python - Trying to Understand Weird Recursion/Object-Attribute/Scope "Gotcha" -


this question has answer here:

i spent hours banging head following problem in python, , can't quite figure out why happened.

say i'm making decision tree class:

class decisiontree:      def __init__(self, name, children = dict()):         self.name = name          self.children = children # <------- here's problem      def add_child(self, child_name, child_tree):         self.children[child_name] = child_tree      def pprint(self, depth = 0):             childkey in self.children:                 tabs = " ".join(["\t" x in xrange(depth)])                 print tabs + 'if ' + self.name + ' ' + str(childkey)                 if (self.children[childkey].__class__.__name__ == 'decisiontree'): # tree, delve deeper                     print tabs + 'and...'                     child = self.children.get(childkey)                     child.pprint(depth + 1 )                 else:                     val = self.children.get(childkey)                     print tabs + 'then predict ' + str( val )                     print "\n"             return '' 

now let's build nonsense tree, , try print it:

def make_a_tree(depth = 0, counter = 0):     counter += 1      if depth > 3:         return 'bottom'     else:          tree = decisiontree(str(depth)+str(counter))          in range(2):             subtree = make_a_tree(depth+1, counter)             tree.add_child(i, subtree)         return tree  foo = make_a_tree() foo.pprint() 

this code leads infinite recursion loop, because tree structure (somehow) mistakenly built 2nd node of tree referring itself.

if change line i've marked above (5th one) tree.children = dict(), things work properly.

i can't wrap head around what's happening here. intention behind code written take argument "children", , if none passed, create empty dictionary , use children.

i'm pretty new python, , i'm trying make learning experience. appreciated.

the problem default arguments functions (and __init__() not exempt) created once. in other words, reusing same dict object every time create new decisiontree.

what need like:

class decisiontree:  def __init__(self, name, children = none):     self.name = name     if children none:         children = {}     self.children = children 

Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -