1

I understand that while defining functions we have to use self as the first argument but in my particular coding example for insert_node method I got an error while calling insert_node(node,new_node) saying 3 arguments expected when I did not use self as the first argument in insert_node

class Node:
 def __init__(self,value=None):
 self.value = value
 self.left = None
 self.right = None
class BST:
 def __init__(self,value=None):
 self.root = Node(value)
 def insert(self,value):
 if self.root == None:
 self.root = Node(value)
 return
 curr = self.root
 new_node = Node(value)
 def insert_node(self,node,new_node):
 if node.value == new_node.value:
 return
 if node.value > new_node.value:
 if node.left is None:
 node.left = new_node
 return
 else:
 insert_node(self,node.left,new_node)
 else:
 if node.right is None:
 node.right = new_node
 return
 else:
 insert_node(self,node.right,new_node)
 insert_node(self,curr,new_node)
asked May 26, 2019 at 21:39
2
  • 4
    Is that the actual indentation? insert_node isn't an instance method, it's a nested function inside one. Commented May 26, 2019 at 21:40
  • 2
    insert_node() is not a method, it is a function nested inside insert(). Commented May 26, 2019 at 21:41

1 Answer 1

4

insert_node() is not a method, it is a function nested inside insert(). You don't need to use self in this function, at all, because it makes no use of that argument, and even if it did, it could access the self reference from the parent insert() method as a closure.

Removing the self argument altogether works:

class BST:
 def __init__(self,value=None):
 self.root = Node(value)
 def insert(self,value):
 if self.root == None:
 self.root = Node(value)
 return
 curr = self.root
 new_node = Node(value)
 def insert_node(node, new_node):
 if node.value == new_node.value:
 return
 if node.value > new_node.value:
 if node.left is None:
 node.left = new_node
 return
 else:
 insert_node(node.left, new_node)
 else:
 if node.right is None:
 node.right = new_node
 return
 else:
 insert_node(node.right, new_node)
 insert_node(curr, new_node)

You can move that function out of the insert() method too, it doesn't need to be nested there:

def insert_node(node, new_node):
 if node.value == new_node.value:
 return
 if node.value > new_node.value:
 if node.left is None:
 node.left = new_node
 return
 else:
 insert_node(node.left, new_node)
 else:
 if node.right is None:
 node.right = new_node
 return
 else:
 insert_node(node.right, new_node)
class BST:
 def __init__(self,value=None):
 self.root = Node(value)
 def insert(self,value):
 if self.root == None:
 self.root = Node(value)
 return
 curr = self.root
 new_node = Node(value)
 insert_node(curr, new_node)

However, this really should be a method on the Node class:

class Node:
 def __init__(self, value=None):
 self.value = value
 self.left = None
 self.right = None
 def insert_node(self, new_node):
 if self.value == new_node.value:
 return
 if self.value > new_node.value:
 if self.left is None:
 self.left = new_node
 return
 else:
 self.left.insert_node(new_node)
 else:
 if self.right is None:
 self.right = new_node
 return
 else:
 self.right.insert_node(new_node)
class BST:
 def __init__(self,value=None):
 self.root = Node(value)
 def insert(self,value):
 if self.root == None:
 self.root = Node(value)
 return
 curr = self.root
 new_node = Node(value)
 curr.insert_node(new_node)

Because you access insert_node() on Node instances (via curr.insert_node(...), self.left.insert_node(...) and self.right.insert_node(...), it is bound to that instance for you by Python, and passed into the method as self.

answered May 26, 2019 at 21:43
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, should I not use nested functions when I just want the call to be internal to a class method?
@vkaul11: no, not really. Python has no privacy model, it expects programmers to be responsible instead. You can name the function _insert_node if you want to flag it as API private, but that's no more than a convention.
@vkaul11: use nested functions when you need access to a closure, not to hide things.
You mean only function closures?
@vkaul11: there are no other kind in Python, not sure what you are asking?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.