在 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()))
在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()))