Я нашел много людей реализовать посетитель шаблон проектирования в питоне следующим образом:Является ли accept() необходимым при реализации шаблона проектирования посетителей в python?
class Node(object):
def accept(self, visitor):
visitor.visit(self)
# some code ...
class Visitor(object):
def visit(self, node):
# invoke corresponding method according to the type of node
# ...
node = Node()
visitor = Vistor()
node.accept(visitor)
Для Java или другого C-подобного статического языка, они используют accept()
для реализации мульти-отправки. Поскольку метод visit()
выбирает конкретный метод переопределения только статическим типом ссылки. Например:
public class MyVisitor implements IVisitor {
void visit(AddNode node);
void visit(Node node);
}
Node node = AddNode(); // AddNode is derived from Node
new MyVisitor().visit(root);
Посетитель будет вызывать метод Node
, а не AddNode
. Таким образом, accept()
необходимо, чтобы получить «реальный» тип, например следующим образом:
public class AddNode extends Node implements IVisitable{
void accept(IVisitor visitor) {
visitor.visit(this)
}
}
Однако тип можно непосредственно извлечь из экземпляра в Python. Visitor
можно осуществить следующим образом:
class Visitor(object):
def visit(self, node):
classname = node.__class__.__name__
_visit = getattr(self, '_visit_'+classname)
_visit(node)
def _visit_AddNode(self, node):
pass
Тогда мы могли бы посетить узел с помощью visit()
непосредственно
node = AddNode()
visitor = Visitor()
visitor.visit(node)
Этот способ является более естественным и простым. Почему люди все еще используют шаблон дизайна Visitor в python с accept()
?