将"指针传递给虚函数"作为Python中的参数

时间:2016-08-05 01:43:57

标签: python c++ reference virtual-functions dispatch

比较 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

我如何传递&#34;指向方法的指针&#34;并将其解析为被覆盖的一个,在Python中实现与在C ++中相同的行为?

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

2 个答案:

答案 0 :(得分:9)

关于你的编辑,你可以做的一件事是使用一个小的包装器lambda来调用你想要引用的方法。这样,方法调用看起来像“常规python代码”,而不是基于基于字符串的访问变得复杂。

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

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

答案 1 :(得分:4)

以下产生您想要的输出:

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")