Unterklassen von C++-Klassen in Python mit Pybind11 – kann ich eine virtuelle Methode haben, die Kwargs übernimmt?Python

Python-Programme
Anonymous
 Unterklassen von C++-Klassen in Python mit Pybind11 – kann ich eine virtuelle Methode haben, die Kwargs übernimmt?

Post by Anonymous »

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 (

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
zur Startmethode von Foo.
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
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

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;

};
Hier sind die Bindungen:

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);
}

Hier ist der Py-Code

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)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post