Unterklassen von C++-Klassen in Python mit Pybind11 – kann ich eine virtuelle Methode haben, die Kwargs übernimmt?
Posted: 27 Dec 2024, 12:49
in meinem C++/Pybind11-Projekt habe ich eine C++-Klasse Foo, die in Python in Unterklassen unterteilt werden kann. Wie üblich durchlief ich den üblichen Prozess, eine Trampolinklasse PyFoo und die üblichen Bindungen zu haben.
Jetzt stellte sich jedoch heraus, dass es nützlich sein würde, den Anfang zu haben Methode von Foo, um Schlüsselwortargumente zu übernehmen ().
In meinem Projekt habe ich auch eine Klasse Caller, die eine Sammlung von Foos enthält. Der Aufrufer stellt eine Methode start bereit, die die start-Methode des erforderlichen foo aufruft und die
weiterleitet zur Startmethode von Foo.
Der Aufruf der Startmethode von Caller aus Python generiert jedoch immer den folgenden Fehler :
Hier ist der vollständige Code zur Reproduktion des Problems. Ist das möglich und wenn ja, was muss ich tun, damit es funktioniert?
Datei foo.h/cpp
Hier sind die Bindungen:
Hier ist der Py-Code
Jetzt stellte sich jedoch heraus, dass es nützlich sein würde, den Anfang zu haben Methode von Foo, um Schlüsselwortargumente zu übernehmen (
Code: Select all
pybind11::kwargs
In meinem Projekt habe ich auch eine Klasse Caller, die eine Sammlung von Foos enthält. Der Aufrufer stellt eine Methode start bereit, die die start-Methode des erforderlichen foo aufruft und die
weiterleitet
Code: Select all
kwargs
Der Aufruf der Startmethode von Caller aus Python generiert jedoch immer den folgenden Fehler :
Code: Select all
TypeError: start() takes 1 positional argument but 2 were given
Datei foo.h/cpp
Code: Select all
#pragma once
#include
#include
// c++ class
class Foo {
public:
Foo() = default;
virtual ~Foo() = default;
virtual void start(pybind11::kwargs args) {}
virtual void update(double) {}
};
// trampoline class
class PyFoo : public Foo {
public:
using Foo::Foo; // Inherit constructors
void PyFoo::start(pybind11::kwargs args) override {
std::cout start(std::move(args));
}
void add(pybind11::object foo) {
_objs.push_back(foo);
_controllers.push_back(foo.cast());
}
private:
std::vector _objs;
std::vector _controllers;
};
Code: Select all
namespace py = pybind11;
PYBIND11_MODULE(untitled3, m) {
py::class_(m, "Foo")
.def(py::init());
py::class_(m, "Caller")
.def(py::init())
.def("add", &Caller::add)
.def("start", &Caller::start);
}
Code: Select all
import untitled3
class Bar(untitled3.Foo):
def __init__(self):
super().__init__()
def start(self, **kwargs):
print('ici')
def update(self, dt):
print('here')
c = untitled3.Caller()
c.add(Bar())
c.add(Bar())
c.start(1)