5

visitor patterninに関する特定の質問に進む前に、以下の (例) コードを検討してくださいpython

class Node:
    def __init__(self):
        self.children = []
    def add(self, node):
        self.children.append(node)
    def check(self):
        print("Node")
        return True
    def accept(self, visitor):
        visitor.visit(self)

class NodeA(Node):
    def check(self):
        print("NodeA")
        return True
class NodeB(Node):
    def check(self):
        print("NodeB")
        return True


class NodeA_A(NodeA):
    def check(self):
        print("NodeA_A")
        return True
class NodeA_B(NodeA):
    def check(self):
        print("NodeA_B")
        return True

class NodeA_A_A(NodeA_A):
    def check(self):
        print("NodeA_A_A")
        return False

class NodeRunner:
    def visit(self, node):
        node.check()
        if len(node.children) > 0:
            for child in node.children:
                child.accept(self)

if __name__ == "__main__":
    n = Node()
    n1 = NodeA()
    n2 = NodeB()
    n11 = NodeA_A()
    n12 = NodeA_B()
    n111 = NodeA_A_A()

    n.add(n1)
    n.add(n2)

    n1.add(n11)
    n1.add(n12)

    n11.add(n111)

    v = NodeRunner()
    v.visit(n)

実行すると、すべてのノードクラスを繰り返しトラバースし、次を返します。

Node
NodeA
NodeA_A
NodeA_A_A
NodeA_B
NodeB

これで問題ありませんが、私の質問に移ります。check各-method がブール値を返すことに気付いたかもしれません(これは実際には複雑なメソッドであるとしましょう)。

上記の例では、クラスcheck内のすべての -method はexcept を返します。すべての基本クラスを失敗させることができるように、訪問中にこれを何らかの形で保存したいと思います。NodeTrueNodeA_A_A

これを説明するのは難しいです。

  • NodeA_A_A返さFalseれた場合は、失敗したいと思いNodeA_A, NodeA and Nodeます。これらのクラスが何を返すかに関係なく。
  • NodeB返さFalseれた場合は、失敗したいと思いNodeます。他のクラスが何を返すかに関係なく。

したがって、 achild-classがどこかで失敗している場合 (check method returns False)、すべての基本クラスを失敗させたいと考えています。

誰にもアイデアはありますか?

4

2 に答える 2

0

あなたが求めているのは、訪問者のパターンではなく、深さ優先検索アルゴリズムを実装する方法についてのようです。これがあなたの質問に対する私の解決策です:

class Node:
    def __init__(self):
        self.children = []
    def add(self, node):
        self.children.append(node)
    def check(self):
        print("Node")
        return True
    def accept(self, visitor):
        return visitor.visit(self)

class NodeA(Node):
    def check(self):
        print("NodeA")
        return True
class NodeB(Node):
    def check(self):
        print("NodeB")
        return True


class NodeA_A(NodeA):
    def check(self):
        print("NodeA_A")
        return True
class NodeA_B(NodeA):
    def check(self):
        print("NodeA_B")
        return True

class NodeA_A_A(NodeA_A):
    def check(self):
        print("NodeA_A_A")
        return False

class NodeRunner:
    def visit(self, node):
        ret = True
        # visit all children
        for child in node.children:
            v = child.accept(self)
            if not v and ret:  # if some child not accepted, then we think that the parent node should also not be accepted
                ret = False

        # check the node
        if not node.check():
            ret = False
        return ret

if __name__ == "__main__":
    n = Node()
    n1 = NodeA()
    n2 = NodeB()
    n11 = NodeA_A()
    n12 = NodeA_B()
    n111 = NodeA_A_A()

    n.add(n1)
    n.add(n2)

    n1.add(n11)
    n1.add(n12)

    n11.add(n111)

    v = NodeRunner()
    print v.visit(n)
于 2013-09-13T02:49:20.277 に答える
0

訪問者パターンを使用して、すべてのノードを訪問しました。1 人の訪問者がすべてのノードにアクセスして実行し、もう 1 人の訪問者が結果をバブルアップします。コードと出力を以下に示します。

class Node(object):
    def __init__(self):
        self.children = []
        self.result = None
    def add(self, node):
        self.children.append(node)
    def check(self):
        self.result = True
        print "Node: result:%s" % self.result
        return self.result
    def accept(self, visitor):
        visitor.visit(self)

class Node_A(Node):
    def __init__(self):
        super(Node_A, self).__init__()
    def check(self):
        self.result = True
        print "Node_A: result:%s" % self.result
        return self.result

class Node_A_A(Node_A):
    def __init__(self):
        super(Node_A_A, self).__init__()
    def check(self):
        self.result = True
        print "Node_A_A: result:%s" % self.result
        return self.result

class Node_A_B(Node_A):
    def __init__(self):
        super(Node_A_B, self).__init__()
    def check(self):
        self.result = True
        print "Node_A_B: result:%s" % self.result
        return self.result

class Node_A_A_A(Node_A_A):
    def __init__(self):
        super(Node_A_A_A, self).__init__()
    def check(self):
        self.result = True
        print "Node_A_A_A: result:%s" % self.result
        return self.result
class Node_A_A_B(Node_A_A):
    def __init__(self):
        super(Node_A_A_B, self).__init__()
    def check(self):
        self.result = False
        print "Node_A_A_B: result:%s" % self.result
        return self.result

class Node_A_B_A(Node_A_B):
    def __init__(self):
        super(Node_A_B_A, self).__init__()
    def check(self):
        self.result = True
        print "Node_A_B_A: result:%s" % self.result
        return self.result



class NodeRunner:
    def visit(self, node):
        if len(node.children) > 0:
            for child in node.children:
                child.accept(self)
        node.check()

class NodeChecker:
    def visit(self, node):
        results = []
        if len(node.children) > 0:
            for child in node.children:
                child.accept(self)
                results.append(child.result)
            node.result = all(results)


if __name__ == "__main__":
    node = Node()
    node_a = Node_A()
    node_a_a = Node_A_A()
    node_a_b = Node_A_B()

    node_a_a_a = Node_A_A_A()
    node_a_a_b = Node_A_A_B()

    node_a_b_a = Node_A_B_A()

    node.add(node_a)

    node_a.add(node_a_a)
    node_a_a.add(node_a_a_a)
    node_a_a.add(node_a_a_b)

    node_a.add(node_a_b)
    node_a_b.add(node_a_b_a)


    print("-------------------")
    nVisitor = NodeRunner()
    nVisitor.visit(node)
    print("-------------------")
    nVisitor = NodeChecker()
    nVisitor.visit(node)
    print("-------------------")
    print "node_a_a_a: result: %s" % node_a_a_a.result
    print "node_a_a_b: result: %s" % node_a_a_b.result
    print "node_a_a: result: %s" % node_a_a.result
    print "node_a_b_a: result: %s" % node_a_b_a.result
    print "node_a_b: result: %s" % node_a_b.result
    print "node_a: result: %s" % node_a.result
    print "node: result: %s" % node.result

出力は以下のとおりです。

-------------------
Node_A_A_A: result:True
Node_A_A_B: result:False
Node_A_A: result:True
Node_A_B_A: result:True
Node_A_B: result:True
Node_A: result:True
Node: result:True
-------------------
-------------------
node_a_a_a: result: True
node_a_a_b: result: False
node_a_a: result: False
node_a_b_a: result: True
node_a_b: result: True
node_a: result: False
node: result: False
于 2013-09-20T08:01:25.740 に答える