我试图为通过boost python公开的类重写python相等运算符。
所以我的代码看起来像:
class_<MyClass, boost::noncopyable, boost::shared_ptr<MyClass> >("MyClass", no_init)
.def("foo", &MyClass::foo)
.
.
.
.def("__eq__", &MyClass::operator==)
.def("__ne__", &MyClass::operator!=)
但是在python中,当我接受代表相同C ++对象的对象的2个实例,但它们来自不同的python对象时,它们永远不相等...
因此:
from myPackage import myClass
v1 = myClass.get("abc")
v2 = myClass.get("abc")
if v1 == v2:
print "true"
else:
print "false"
始终打印为假。(为简单起见,我从对象中省略了get函数定义)
有任何想法吗?
考虑编写一个C ++测试用例MyClass::operator==()
以验证其实现。暴露运算符的Boost.Python代码是正确的。
这是一个示例,展示了将C ++类的比较运算符公开为相等和不相等的丰富比较方法:
#include <iostream>
#include <string>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class foo
{
public:
foo(const char* value) : value_(value) {}
foo(const foo&) = delete;
foo& operator=(const foo&) = delete;
bool operator==(const foo& rhs)
{
std::cout << "foo::operator==()" << std::endl;
return value_ == rhs.value_;
}
bool operator!=(const foo& rhs)
{
std::cout << "foo::operator!=()" << std::endl;
return !(*this == rhs);
}
std::string get_value() const { return value_; }
void set_value(std::string value) { value_ = value; }
private:
std::string value_;
};
boost::shared_ptr<foo> make_foo(const char* value)
{
return boost::make_shared<foo>(value);
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<foo, boost::shared_ptr<foo>, boost::noncopyable>(
"Foo", python::no_init)
.def("__init__", python::make_constructor(&make_foo))
.def("__eq__", &foo::operator==)
.def("__ne__", &foo::operator!=)
.add_property("value", &foo::get_value, &foo::set_value)
;
}
互动用法:
>>> import example
>>> foo1 = example.Foo("abc")
>>> foo2 = example.Foo("abc")
>>> foo3 = example.Foo("def")
>>> assert(foo1 == foo1)
foo::operator==()
>>> assert(foo1 == foo2)
foo::operator==()
>>> assert(foo1 is not foo2)
>>> assert(foo1 != foo3)
foo::operator!=()
foo::operator==()
>>> foo1.value = foo3.value
>>> assert(foo1 != foo2)
foo::operator!=()
foo::operator==()
>>> assert(foo1 == foo3)
foo::operator==()
从上面的输出中可以看到,C ++比较运算符是从Python调用的。
在示例中,make_foo()
工厂函数创建唯一的C ++foo
实例。因此,我选择通过包装make_foo()
为构造函数并将其公开为方法来将工厂方法的实现细节隐藏到Python中__init__
。如此处所示,如果通过静态方法创建对象,仍然可以检查是否相等。另一方面,如果静态工厂方法get()
可以将句柄返回给现有foo
实例,则可以期望相等和身份比较都可以在Foo
Python对象上进行(例如,assert(Foo.get("abc") is Foo.get("abc"))
要返回对同一Python对象的引用,则需要管理相关的PyObject
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句