Сравните следующий код в C++:Передача "указатель на виртуальную функцию" в качестве аргумента в Python
#include <iostream>
#include <vector>
struct A
{
virtual void bar(void) { std::cout << "one" << std::endl; }
};
struct B : public A
{
virtual void bar(void) { std::cout << "two" << std::endl; }
};
void test(std::vector<A*> objs, void (A::*fun)())
{
for (auto o = objs.begin(); o != objs.end(); ++o)
{
A* obj = (*o);
(obj->*fun)();
}
}
int main()
{
std::vector<A*> objs = {new A(), new B()};
test(objs, &A::bar);
}
и Python:
class A:
def bar(self):
print("one")
class B(A):
def bar(self):
print("two")
def test(objs, fun):
for o in objs:
fun(o)
objs = [A(), B()]
test(objs, A.bar)
C++ код будет печататься:
one
two
в то время как Python код напечатает
one
one
Как я могу передать «указатель на метод» и разрешить его переопределенном один, достигая того же поведения в Python, как и в C++?
Чтобы добавить контекст и объяснить, почему я изначально думал об этом шаблоне. У меня есть дерево, состоящее из узлов, которые могут быть подклассифицированы. Я хотел бы создать общую функцию обхода графа, которая берет узел графика, а также функцию, которая может быть переопределена в подклассах узлов графа. Функция вычисляет некоторое значение для узла, заданные значения, рассчитанные для соседних узлов. Цель состоит в том, чтобы вернуть значение, рассчитанное для данного узла (что требует прохождения всего графика).
Рассматривали ли вы структурировать код Python, так что вы * не * пытаться повторить семантику другой язык? Я чувствую, что чем больше Pythonic способ сделать это не имеет ничего общего с наследованием или динамической диспетчеризацией. –
Я согласен, проблема в том, что у меня нет лучшего шаблона для моей проблемы. Смотрите описание проблемы. Я бы предпочел решение Питонов. –
Похоже, вы хотите шаблон посетителя. –