current position:Home>Boost (5): extract the type of C + + language and extract class from Python object

Boost (5): extract the type of C + + language and extract class from Python object

2022-05-15 06:01:57Xiangdi


python and c++ The difference between data types is a common problem in conversion , Some simple data types can be generalized , But there are many types that cannot be used directly . When faced with such problems ,boost.python Provided extract Class is a convenient solution . This article is used to record my understanding of extract The understanding of the .

1. explain

1.1 Extract Introduce

Extract yes Boost.Python Used from Python Object c++ The class of the object , Through this class, we can put some Python The object of is converted to C++ The object of language . Such as the boost::python::str A variable of type is converted to char * Type variable .

Extract The executive member of must be a non overloaded static function , Its single parameter is Python object type . Acceptable Python Object types include from PyObject The derived ones are public ( And clear ) Object type of , As well as PyObject Layout compatible POD type .

notes : If you want to python Object c++ type , Then the object must first contain this type of content .

1.2 Usage method

Here are some basic ways to use .
1. obtain python The value of the object

int a = boost::python::extract<int>(x)

from python object x Extract from int The content of .

2. Check with the constructor before extraction

int g(object x)
    extract<int> get_int(x);
    if (get_int.check())
        return get_int();
        return 0;

Constructors get_int First call check() To check if you can x convert to int Data of type .

3. Use extract Directly modify variable objects
We can use extract Without copying the target object , Direct and convenient modification boost::python::object And its derived types PyObject*.

namespace bp = boost::python;

// bp::object x;
dict d = bp::extract<bp::dict>(x.attr("__dict__"));
d["whatever"] = 3;          // modifies x.__dict__ !

// PyObject* pyobj;
PyObject* __dict__ = PyObject_GetAttrString(pyobj, const_cast<char*>("__dict__"));
// (see also
bp::dict dictobj = bp::extract<bp::dict>(__dict__);
dictobj["whatever"] = 3;          // modifies pyobj __dict___!

4. Extract elements from more complex structures
In order to extract elements from complex structures such as lists and tuples , We must nest extraction calls . Suppose there is an element of type tuple Of list Variable , Extract from it tuple The data in .

boost::python::list l1 = [(1, 2), (3, 4), (5, 6)];


2. Example

To demonstrate , Prior to RealWorld Add a... To your class ShowRelatives() function , This function will pass in python list Type data converted to c++ Under the std::vector.

Declare and define functions

stay classes.hpp Of RealWorld Add function declaration under class :

void ShowRelatives(boost::python::list &rels);

Its definition is as follows :

void RealWorld::ShowRelatives(python::list &rels)
    std::vector<char *> rel(len(rels), 0);

    for (int i = 0; i < len(rels); i++){
        rel[i] = python::extract<char *> (rels[i]);

    for (int i = 0; i < rel.size(); i++)
        std::cout << rel[i] << " ";
    std::cout << std::endl;

Added to the python modular

.def ("ShowRelatives", &RealWorld::ShowRelatives, python::args("rels"))

A simple test

python The test procedure is as follows :

#!/usr/bin/env python

import classes

t1 = classes.RealWorld("Xiangdi", 'm')
relative = ("father", "mother", "brother", "sister")

Running results

notes :python list It doesn't seem to convert directly to std::vectorstd::string In the form of , Because when I try this, I always report mistakes :

Traceback (most recent call last):
  File "", line 9, in <module>
RuntimeError: basic_string::_M_construct null not valid

3. extract Class explanation

extract Class is defined in <boost/python/extract.hpp> In file .

3.1 extract Definition

template <class T>
struct extract
    : converter::select_extract<T>::type
    typedef typename converter::select_extract<T>::type base;
    typedef typename base::result_type result_type;
    operator result_type() const
        return (*this)();
    extract(api::object const&);

among T Indicates the target to be extracted c++ type . Two usages are supported :

  • extract(o) : Generate an implicit conversion to T The temporary object of ( You can also perform explicit conversion through the function call operator of the object ). however , If o None of them can be converted into T Object of type , Will trigger Python TypeError abnormal .
  • extract x(o): This method constructs an extractor , In this extractor check() The member function asks if the transformation is available , Without throwing an exception .

3.2 Constructors

extract(api::object const&);

In the structure extract When an instance , You can pass in two parameters , One is Python Object pointer , The other is object reference . From the implementation of the two functions , The second method is actually to pass the pointer of the reference object to the parent object inside the function body .

3.3 Member functions

Only some member functions are introduced here .

operator result_type() const

result_type() The function is used to store python The pointer to the object is converted to T or T& type , That is, we are instantiating extractor The action that will run automatically after . If something goes wrong ( such as python Object does not contain T Type of content ), Function will trigger TypeError.

I can't see from the definition code above ,extract The parent class of also provides some additional member functions , such as check().

bool check() const;

This function is in the extract In the constructor , To examine python Whether the object can be converted to T or T& type , If you can't return false. It should be noted that even if it cannot be converted, it will not trigger python abnormal .

Reference material

Chapter 5. To/From Python Type Conversion

copyright notice
author[Xiangdi],Please bring the original link to reprint, thank you.

Random recommended