通过a";指向虚拟函数的指针;Python中的as参数

通过a";指向虚拟函数的指针;Python中的as参数,python,c++,reference,virtual-functions,dispatch,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; } }

比较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);
}
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++(

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

以下操作将生成所需的输出:

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来调用您想要引用的方法。这样,方法调用看起来像“常规python代码”,而不是基于字符串访问的复杂内容

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

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

您是否考虑过对Python代码进行结构化,以避免尝试用不同的语言复制语义?我觉得更具python风格的方法与继承或动态调度无关。我同意,问题是我没有更好的模式来解决我的问题。有关问题描述,请参见编辑。我更喜欢Pythonic解决方案。听起来你想要访问者模式。你能发布一个(简化的)示例,说明如何用Python实现它吗?这从字面上回答了这个问题,但我认为它根本不代表OP试图实现的目标。当然这个程序不会在更复杂的例子中扩展。@uh-oh:IMO它回答了这个问题,并且代表了在Python没有指针的情况下OP试图完成的任务。此外,它应该“缩放”以及C++版本。这就是我的观点。Python没有指针或多重分派,因此我希望有一种更惯用的方法来实现相同的目标。所有这些都强化了错误的做事方式。@uh-oh:除了你,谁说了关于多重调度的事?我的答案中的代码使用继承,并展示了引用实例的变量属性的惯用方法。请随意发布您自己的答案,即使是“您不能在Python中这样做”。谢谢您的回答。我认为它确实回答了我最初提出的问题。我想到了一个类似的解决方案,但我希望有一个更干净/更好的解决方案。如果没有,我建议用“这不能在Python中以任何其他方式完成”来扩展这个答案,除了:,我也很高兴听到关于解决我的问题的最佳模式的意见(参见编辑)。这似乎是一种更干净、更具Python风格的解决问题的方法。然而,它不允许动态调度,这是可以用另一个答案(如果需要的话)来模拟的。
bar
方法调用将被动态调度。我的术语可能已关闭。我的意思是,使用这种方法,不可能处理
bar
A
B
中采用不同参数的情况,例如,在
B
中,它采用附加参数。在字符串方法中,
test
可以根据
obj
的类型选择对
bar
应用不同的参数。让A和B采用不同的参数会很奇怪(使用通用方法的目的是共享一个接口…)但并没有什么可以阻止测试检查objs列表中对象的类型。唯一的问题是如果A和B采用不同数量的参数,但您可以通过将lambda转换为vararg函数来解决:
lambda x,*args:x.bar(*args)
同意这是一种比我自己的答案更好的方法。向上投票。。。