在 Python 中传递 "pointer to a virtual function" 作为参数

Passing a "pointer to a virtual function" as argument in Python

C++中比较以下代码:

#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

如何传递 "a pointer to a method" 并将其解析为被覆盖的那个,从而在 Python 中实现与在 C++ 中相同的行为?

添加一些上下文并解释为什么我最初想到这个模式。我有一个由可以子类化的节点组成的树。我想创建一个通用的图遍历函数,它采用图的一个节点以及一个可能在图节点的子类中被覆盖的函数。该函数计算节点的一些值,给定相邻节点的计算值。目标是 return 为给定节点计算的值(这需要遍历整个图)。

以下生成您想要的输出:

class A:
    def bar(self):
        print("one")

class B(A):
    def bar(self):
        print("two")

def test(objs, funcname):
    noop = lambda: None
    for o in objs:
        getattr(o, funcname, noop)()

objs = [A(), B()]
test(objs, "bar")

关于您的编辑,您可以做的一件事是使用一个小的包装器 lambda 来调用您要引用的方法。这样方法调用看起来像 "regular python code" 而不是基于字符串访问的复杂方法。

在您的示例中,唯一需要更改的部分是对 test 函数的调用:

test(objs, (lambda x: x.bar()))