Boost.Python은 PyObject
와 상호 작용하는 필요성을 최소화하도록 설계하고, 자주하여이 작업을 수행한다 : 높은 수준의 타입 래퍼를 제공
- .
boost::python::object
을 통해 파이썬 객체의 인터페이스에 대한 액세스를 허용합니다.
예를 들어 파이썬에서와 비슷한 방식으로 C++을 통해 파이썬 객체의 인터페이스에 액세스 할 수 있습니다. 길이 제로의 처리 None
가 제공 될 때 기본값을 만들고,이 방법은 작동
namespace python = boost::python;
python::object slice = get_slice_object();
python::object start = slice.attr("start");
std::size_t start_index = !start.is_none()
? python::extract<std::size_t>(start) // Extract index.
: 0; // Default.
동안, 많은 상용구 코드 발생하는 경향이있다 : 다음은 파이썬 slice
인스턴스를 참조하는 boost::python::object
의 start
속성에 접근 보여줍니다 슬라이스 및 음수 인덱스를 양수 인덱스로 변환합니다. 이 경우 Boost.Python은 많은 상용구 코드를 제거하는 get_indices()
멤버 함수가있는 상위 수준 유형 래퍼 boost::python::slice
을 제공합니다. 여기에 완전한 최소한의 예입니다
#include <vector>
#include <boost/range/algorithm.hpp>
#include <boost/range/irange.hpp>
#include <boost/python.hpp>
#include <boost/python/slice.hpp>
/// @brief Mockup class that creates a range from 0 to N.
struct counter
{
counter(std::size_t n)
{
data.reserve(n);
boost::copy(boost::irange(std::size_t(0), n), std::back_inserter(data));
}
std::vector<int> data;
};
/// @brief Handle slicing for counter object.
boost::python::list spam_getitem(
const counter& self,
boost::python::slice slice)
{
namespace python = boost::python;
python::list result;
// Boost.Python will throw std::invalid_argument if the range would be
// empty.
python::slice::range<std::vector<int>::const_iterator> range;
try
{
range = slice.get_indices(self.data.begin(), self.data.end());
}
catch (std::invalid_argument)
{
return result;
}
// Iterate over fully-closed range.
for (; range.start != range.stop; std::advance(range.start, range.step))
{
result.append(*range.start);
}
result.append(*range.start); // Handle last item.
return result;
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<counter>("Counter", python::init<int>())
.def("__getitem__", &spam_getitem)
;
}
대화 형 사용 :
>>> from example import Counter
>>> counter = Counter(5)
>>> assert(counter[:] == [0,1,2,3,4])
>>> assert(counter[:-2] == [0,1,2])
>>> assert(counter[-2:] == [3,4])
>>> assert(counter[::2] == [0,2,4])
>>> assert(counter[1::2] == [1,3])
>>> assert(counter[100:] == [])
좋은 예! 슬라이스와 인덱스 (예 : counter [2 : -1] 및 counter [2])를 모두 처리 할 수 있도록 확장 할 수 있습니까? – Felix