我想从我的 C++ 扩展模块中返回以下 python 类的一个实例,它模仿 boost::tribool 的三态逻辑:
class Tribool(object):
def __init__(self, value = None):
if any(value is v for v in (False, True, None)):
self.value = value
else:
raise ValueError("Tribool must be False, True or None")
def __nonzero__(self):
raise TypeError("Tribool may not be used as an implicit bool")
def __eq__(self, other):
if isinstance(other, Tribool):
return self.value is other.value
if any(other is v for v in (False, True, None)):
return self.value is other
raise TypeError("Tribool can only be compared to another Tribool or False, True, or None")
def __ne__(self, other):
return not (self == other)
def __invert__(self):
if self.value is False:
return Tribool(True)
elif self.value is True:
return Tribool(False)
elif self.value is None:
return Tribool(None)
raise ValueError("Tribool must be False, True or None")
def __and__(self, other):
if (self.value is False) or (other.value is False):
return Tribool(False)
if (self.value is None) or (other.value is None):
return Tribool(None)
return Tribool(True)
def __or__(self, other):
if (self.value is True) or (other.value is True):
return Tribool(True)
if (self.value is None) or (other.value is None):
return Tribool(None)
return Tribool(False)
def __xor__(self, other):
if (self.value is None) or (other.value is None):
return Tribool(None)
if self == other:
return Tribool(False)
return Tribool(True)
def __str__(self):
if any(self.value is v for v in (False, True, None)):
return str(self.value)
raise ValueError("Tribool must be False_, True_ or Maybe_")
def __repr__(self):
return "Tribool(%s)" % str(self)
我相信我需要编写一个 to_python_converter,但我不知道如何为用户定义的 python 类型编写一个转换器。我已经阅读了 Boost Python 文档并使用 Google 进行了搜索,但没有找到可以借鉴的好例子。感谢您的帮助。
更新:
以下 C++ 代码会将 tribool 转换为 Python 值 True、False 和 None,这是部分解决方案:
struct tribool_to_Tribool
{
static PyObject *convert(tribool const& value)
{
if (value == true) return boost::python::incref(boost::python::object(true).ptr());
else if (value == false) return boost::python::incref(boost::python::object(false).ptr());
else return boost::python::incref(boost::python::object().ptr());
}
};
to_python_converter<tribool,tribool_to_Tribool>();
我无法弄清楚的部分是如何从转换例程中返回纯 Python Tribool 类的实例而不是值 True、False 和 None。
最佳答案
这可以通过与从 Python 方法返回 Tribool
相同的方式来完成。在任何一种语言中,都需要获取 Tribool
Python 类对象的句柄,然后调用它。返回的对象将是 Tribool
类型的实例。
例如:
from tribool import Tribool
x = Tribool(False)
相当于:
namespace python = boost::python;
python::object tribool_class = python::import("tribool").attr("Tribool");
python::object x = tribool_class(false);
下面是一个简化的示例,其中用户定义的 Python 模块(spam
)包含一个 Python 类(Spam
)和一个 C++ Python 扩展模块(example
) 提供了一个 make_spam
函数来创建 spam.Spam
对象。
spam.py
Python 模块:
class Spam(object):
def __init__(self, value):
self.value = value
def __str__(self):
return self.__repr__() + " has a value of " + str(self.value)
example.cpp
扩展模块:
#include <boost/python.hpp>
boost::python::object make_spam(boost::python::object value)
{
// from spam import Spam
// return Spam(value)
return boost::python::import("spam").attr("Spam")(value);
}
BOOST_PYTHON_MODULE(example)
{
boost::python::def("make_spam", &make_spam);
}
交互式 Python:
>>> import example
>>> print example.make_spam(False)
<spam.Spam object at 0xb74be1ac> has a value of False
>>> print example.make_spam(True)
<spam.Spam object at 0xb74be10c> has a value of True
>>> print example.make_spam(None)
<spam.Spam object at 0xb74be1ac> has a value of None
关于c++ - 在扩展模块中为用户定义的 python 类 boost Python to_python_converter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20823067/