Python3 and recursive class

2019-07-19 04:56发布

I want to define own tree-like class. I've written code like this:

class forest:
        class tree:
                def __init__(self):
                        self.var_a = []
                        self.var_b = []
                        #Or something as simple
                def mk(self,something):
                        #Some instructions
                        self.a = tree()
                        b_var = self.a.mk(a_var)
                        self.b = tree()
                        c_var = self.a.mk(b_var)
                        #Some instructions
                        return ret
        #Some code for class forest

Well tree() doesn't work.

NameError: global name 'tree' is not defined

The error for self.tree():

AttributeError: 'tree' object has no attribute 'tree'

I do not know how (or if) to use self.__init__ or self.__new__ in this context.

The question
It is possible to use recursive class in Python3? How does the code for this look like?

2条回答
放我归山
2楼-- · 2019-07-19 05:17

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.

查看更多
不美不萌又怎样
3楼-- · 2019-07-19 05:34

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.

查看更多
登录 后发表回答