В моем проекте C++/Pybind11 у меня есть класс C++ Foo, который можно создать в Python. Как обычно, я прошел обычный процесс создания класса батута PyFoo и привычных привязок.
Однако теперь оказалось, что было бы полезно иметь начало метод Foo для получения аргументов ключевых слов (pybind11::kwargs).
В моем проекте также есть класс Caller, который содержит коллекцию Foo. Вызывающий предоставляет метод start, который вызывает метод start требуемого foo, пересылая
kwargs к методу start Foo.
Однако вызов метода start Caller из Python всегда генерирует следующую ошибку :
TypeError: start() takes 1 positional argument but 2 were given
Вот полный код, воспроизводящий проблему. Возможно ли это, и если да, что мне следует сделать, чтобы это заработало?
Файл foo.h/cpp
#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;
};
Вот привязки:
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);
}
Вот код Py
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)
Подробнее здесь: https://stackoverflow.com/questions/793 ... -method-ta