【问题标题】:Python3 and recursive classPython3 和递归类
【发布时间】:2012-01-12 07:36:55
【问题描述】:

我想定义自己的树状类。我写过这样的代码:

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

tree() 不行。

NameError: global name 'tree' is not defined

self.tree() 的错误:

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

我不知道如何(或是否)在这种情况下使用 self.__init__self.__new__

问题
可以在 Python3 中使用递归类吗?这个代码看起来如何?

【问题讨论】:

  • 你想要forest.tree,因为tree 类在forest 类中。
  • 它看起来有效。但是,我在编写简单的测试用例时遇到了问题......
  • @Michas 如果您的问题已被回答,请将其标记为已接受。

标签: python python-3.x class oop recursion


【解决方案1】:

您无需嵌套类即可实现container pattern

Tree 类移到 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()

问题:

可以在 Python3 中使用递归类吗?代码如何 这个样子?

直接回答:

嵌套类定义在 Python 中没有任何好处,因为它们的范围不嵌套(内部类的内容不能直接引用封闭类)。

因此,Python 中通常的模式是创建两个类,而不是直接相互引用(使用组合而不是继承)。

后续评论:

嗯。我不需要使用类。函数和字典 就够了。

函数和字典总是足够的(Python 的早期版本没有类)。 OTOH,我们发现类是一种组织代码的便捷方式,可以清楚地说明哪些函数对哪些数据进行操作。 如何做是一个品味问题。

稍后的评论:

嵌套类有一个好处。它的定义并不存在于 全局范围。

这也可能是一个缺点,使重用代码更加困难,测试更加困难,并且可能会混淆自省工具。

【讨论】:

  • 好吧。我不需要使用类。函数和字典就足够了。
  • @Michas:这会带来巨大的不便,而且不习惯。不嵌套类至少同样方便,而且在 Python 世界中更为常见。
  • 我有时会发现嵌套类可以代替仅出于命名空间目的而创建单独的模块。例如,我有一个类tree,然后里面有一个类,它是一个名为deciduous 的子类,因此用户可以通过tree.deciduous 访问该类。另外,当我使用元类时,我喜欢直接在类中声明元类,而不是单独声明。但是,是的,可以说类嵌套有用的情况有点狭窄。
  • @Michas:嵌套类的可读性较少。它只会造成混乱,因为人们希望在全局范围内定义该类。仅当您需要动态定义类或当类需要特定的动态范围时,将类定义放在其他范围内才有用(但仍然令人困惑)。只是嵌套类没有任何好处,只有缺点。
  • @Michas:但是让它们嵌套只会更多令人困惑。并且在全局范围内拥有超过 7 个类并不令人困惑,除非您的命名令人困惑。大多数人不能一次记住超过 3 到 5 件事情,但这并不能阻止他们使用具有大量类和方法的模块。如果要按命名空间分隔类,我建议使用模块。同样:嵌套类增加混乱和复杂性。 没有任何好处
【解决方案2】:

我刚刚对此进行了实验,它可以在 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()

这样您就不必使用“树”类污染全局名称空间

如果您因为混淆/可读性问题不喜欢这个,您可以随时按照前面所述创建一个单独的树类。

【讨论】:

    猜你喜欢
    • 2017-04-23
    • 1970-01-01
    • 2016-02-06
    • 2012-11-11
    • 2022-11-30
    • 2010-10-23
    • 2018-06-20
    • 2017-02-16
    • 2017-06-24
    相关资源
    最近更新 更多