Boost.Python – Как вернуться по ссылке?

Я использую Boost.Python для создания модулей Python из классов C ++. И я столкнулся с проблемой со ссылками.

Упорядочите следующий случай, когда у меня есть класс Foo с перегруженными методами get, которые могут либо возвращаться по значению, либо по ссылке.

Указать, что нужно использовать значение return, было легко, как только я набрал подпись. Но я думаю, что также возможно вернуть ссылку, используя return_value_policy . Однако, используя то, что казалось подходящим ( doc ); return_value_policy<reference_existing_object> , похоже, не работает.

Я неправильно понял, что он делает?

 struct Foo { Foo(float x) { _x = x; } float& get() { return _x; } float get() const { return _x; } private: float _x; }; // Wrapper code BOOST_PYTHON_MODULE(my_module) { using namespace boost::python; typedef float (Foo::*get_by_value)() const; typedef float& (Foo::*get_by_ref)(); class_<Foo>("Foo", init<float>()) .def("get", get_by_value(&Foo::get)) .def("get_ref", get_by_ref(&Foo::get), return_value_policy<reference_existing_object>())//Doesn't work ; } 

Примечание. Я знаю, что было бы опасно ссылаться на существующий объект без управления жизненным циклом.

Обновить:
Похоже, что он работает для объектов, но не для базовых типов данных.
Возьмите этот пересмотренный пример:

 struct Foo { Foo(float x) { _x = x; } float& get() { return _x; } float get() const { return _x; } void set( float f ){ _x = f;} Foo& self(){return *this;} private: float _x; }; // Wrapper code using namespace boost::python; BOOST_PYTHON_MODULE(my_module) { typedef float (Foo::*get_by_value)() const; class_<Foo>("Foo", init<float>()) .def("get", get_by_value(&Foo::get)) .def("get_self", &Foo::self, return_value_policy<reference_existing_object>()) .def("set", &Foo::set); ; } 

Который в тесте дал ожидаемый результат:

 >>> foo1 = Foo(123) >>> foo1.get() 123.0 >>> foo2 = foo1.get_self() >>> foo2.set(1) >>> foo1.get() 1.0 >>> id(foo1) == id(foo2) False 

4 Solutions collect form web for “Boost.Python – Как вернуться по ссылке?”

В Python существует концепция неизменных типов . Неизменяемый тип не может изменить его значение. Примерами встроенных неизменяемых типов являются int, float и str.

Сказав это, вы не можете делать то, что хотите, с boost::python , потому что сам Python не позволяет вам изменять значение возвращаемого функцией функции float.

Второй пример показывает одно решение, другое – создать тонкие обертки и разоблачить это:

 void Foo_set_x(Foo& self, float value) { self.get() = value; } class_<Foo>("Foo", init<float>()) ... .def("set", &Foo_set_x); ; 

Это лучшее решение, чем изменение исходного класса C ++.

Я думаю, что вы хотите вернуть внутреннюю ссылку . Я использовал его раньше, чтобы сделать что-то подобное.

Изменить: Последний документ

Я мало знаю о Boost.Python, поэтому я могу неправильно понять вопрос, и в этом случае это совершенно бесполезно. Но здесь идет:

В Python вы не можете выбирать между возвратом по ссылке или по значению, это различие не имеет смысла в Python. Я нахожу, что легче всего думать об этом, так как все обрабатывается ссылкой.

У вас просто есть объекты, и у вас есть имена для этих объектов. Так

 foo = "ryiuy" 

Создает строковый объект «ryiuy», а затем позволяет ссылаться на этот строковый объект с именем «foo». Поэтому в Python, когда вы что-то передали, вы передаете этот объект. В этом нет «значений», поэтому вы не можете передать значение. Но опять же, это также верная точка зрения, что нет ссылок, просто объектов и их имен.

Таким образом, я думаю, ответ заключается в том, что когда вы получаете ссылку на C, вам нужно передать ссылку на объект, ссылающийся на Python. И когда вы получаете значение на C, вам нужно передать ссылку на объект, который вы создаете из этого значения, на Python.

Вы уверены, что объект c ++ копируется? Каждый раз вы будете получать новый объект python, но который ссылается на один и тот же объект c ++. Как вы определяете, что объект был скопирован?

  • Boost.Python: как открыть std :: unique_ptr
  • Передайте объект типа (класс, а не экземпляр) из python в c ++
  • Запустить python в C ++
  • Boost :: Python, преобразование кортежа в работы Python, вектор <tuple> не
  • Что такое libpython3.so по сравнению с libpython3.5m.so, построенным из источника python 3.5.2?
  • Boost :: python Выставление функций C ++ с использованием и возвратом шаблонов
  • Объединение массивов в Boost Python
  • Boost Python: полиморфный контейнер?
  • Нужна помощь при запуске с Boost.Python
  • Повысить переносимость Python
  • C ++ iostreams и python
  •  
    Interesting Posts for Van-Lav

    Отключить вставку выделенного текста при нажатии правой кнопки мыши в tkinter на OS X

    Почему доступ к переменной класса из класса требует «я» в Python?

    Кто-нибудь знает какую-либо услугу API расписания поездов?

    Ссылки на mutables (например, списки) как значения в словарях Python – что лучше всего?

    PyQt + ярлык для запуска кнопки

    Как получить список IP-адресов?

    Разбиение страницы в Django Rest Framework

    Ошибка импорта: авторизация API Google Analytics

    Преобразование из кадра данных Pandas в тензорный объект TensorFlow

    Как предотвратить состояние гонки, когда несколько процессов пытаются записать и затем прочитать из файла одновременно

    Как поместить tcp-сервер в другой поток в python

    как сделать мой скрипт python легко переносимым? или как скомпилировать в двоичные файлы со всеми зависимостями модулей?

    Неожиданная кривая производительности от сортировки слияния CPython

    Python beautifulsoup – получение входного значения

    OpenCV + python – захват кадров из видеофайла

    Python - лучший язык программирования в мире.