Consider replacing NoneType child trees with an empty tree object with a None root. Also, to answer the question in your code comment, I think defaulting keyfunc = lambda x: x is reasonable, and it simplifies your code further.
class BinarySearchTree:
def __init__(self, node, keyfunc=lambda x: x):
self.root = node
self.keyfunc = keyfunc
if node is not None:
self.left = self.new_empty()
self.right = self.new_empty()
def new_empty(self):
"""Create a new empty child for this tree"""
return BinarySearchTree(None, self.keyfunc)
def add(self, key, data=None):
node = Node(key, data)
if self.root is None:
self.root = node
self.left = self.new_empty()
self.right = self.new_empty()
else:
parent = self.root.key
if self.keyfunc(key) < self.keyfunc(parent):
self.left.add(key, data)
elif self.keyfunc(key) > self.keyfunc(parent):
self.right.add(key, data)
def inorder(self):
if self.root is not None:
self.left.inorder()
print(self.root.key, end=' ')
self.right.inorder()
For ease of use, you may also choose to add a definition like the following:
def __bool__(self):
return self.root is not None
This lets you simplify a test to see if a node is empty by doing something like if self: instead of if self.root is not None: in the inorder method or if self.left: to see if there is a left child tree instead of if self.left.root is not None:.
There is no need for "recursive class definitions". All you need to do to allow chaining is to return self in your methods (or a instance of the same class if your objects are not mutable or some methods shouldn't modify the input object).
Example:
>>> class SQL(object):
... def __init__(self):
... self.columns = []
... def select(self, col):
... self.columns.append(col)
... return self
...
>>> s = SQL()
>>> s.select('foo').select('bar').columns
['foo', 'bar']
You are confusing classes with methods.
select is a method on an instance of class sql, not a nested class. It could return another instance.
class SelectStatement(object):
def select(self, tablename):
return SelectStatement()
class SQL(object):
def select(self, tablename):
return SelectStatement()
Take a look at the source code of SQLAlchemy; it does exactly that; generate SQL from a structure python classes, where you can refine a query by calling methods on instances in just such a manner. A series of joins for example, can be chained:
q = session.query(User).join(User.orders).join(Order.items).join(Item.keywords)
Each method of a class has to have self as a first parameter, i.e. do this:
def recur(self, num):
and it should work now.
Basically what happens behind the scene is when you do
instance.method(arg1, arg2, arg3, ...)
Python does
Class.method(instance, arg1, arg2, arg3, ....)
This is a code example that actually works
class Card():
def __init__(self,cardsPlayedList,cardPosition):
self.cardsPlayedList = cardsPlayedList
self.cardPosition = cardPosition
# self.cardPosition
def getNewCard(self,cardPosition):
cardNum = 0
cardInList = False
cardNum = random.randint(1,len(cardList)-1) # Get random card from List - 1 to 52
for x in self.cardsPlayedList:
if(cardNum == x):
cardInList = True
if(cardInList == False):
self.cardsPlayedList.insert(self.cardPosition, cardNum) # if card not already played then store in list
return cardNum
else:
return self.getNewCard(cardPosition)
You don't need to nest the classes in order to implement a container pattern.
Move the Tree class outside of Forest. Each time a tree is instantianted, it can add itself to the forest:
class Forest:
def __init__(self):
self.mytrees = []
def add(self, tree):
self.mytrees.append(self)
def drop_leaves(self):
for tree in self.mytrees:
tree.drop_leaves()
class Tree:
def __init__(self, forest):
forest.add(self)
self.var_a = []
self.var_b = []
#Or something as simple
def drop_leaves(self):
print 'Drop'
sherwood = Forest()
t1 = Tree(sherwood)
t2 = Tree(sherwood)
sherwood.drop_leaves()
The question:
It is possible to use recursive class in Python3? How does the code for this look like?
Straight answer:
Nesting class definitions does not confer any benefit in Python because their scopes don't nest (the contents of the inner class cannot refer directly to the enclosing class).
Accordingly, the usual pattern in Python is to make two of more classes than can refer directly to one another (using composition rather than inheritance).
Subsequent comment:
Well. I don't need to use classes. The functions and dictionaries would be enough.
Functions and dictionaries are always enough (the early versions of Python did not have classes). OTOH, we've found that classes are a convenient way to organize code, making it clear which functions operate on which data. How you do it is a matter of taste.
A later comment:
There is one benefit of nested class. Its definition doesn't reside in global scope.
That can be a disadvantage as well, making it more difficult to reuse code, more difficult to test, and possibly confounding introspection tools.
I just experimented with this and it can be done in Python3
class forest:
#Interal Class _tree
class _tree:
def __init__(self):
self.var_a = []
self.var_b = []
#Or something as simple
def mk(self,something):
#Some instructions on self.var_a or self.var_b
def __init__(self):
#Assign internal class _tree to public variable tree
self.tree=self._tree()
sherwood=forest()
sherwood.tree.mk()
This way you don't have to pollute global name space with a 'tree' class
Though if you dislike this due to confusion/readibility issues, you can always make a separate tree class as previously described.