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