Boost Python重写相等运算符
Boost Python overriding equality operator
我正试图覆盖我通过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++对象,但来自不同的python对象时,它们永远不相等。。。
因此:
from myPackage import myClass
v1 = myClass.get("abc")
v2 = myClass.get("abc")
if v1 == v2:
print "true"
else:
print "false"
总是打印错误。(为了简单起见,我省略了对象中的get函数定义)
有什么想法吗?
考虑为MyClass::operator==()
编写一个C++测试用例来验证其实现。公开运算符的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()
封装为构造函数并将其公开为__init__
方法来向Python隐藏工厂方法的实现细节。如本文所示,如果通过静态方法创建对象,则仍然可以检查相等性。另一方面,如果像get()
这样的静态工厂方法可以返回现有foo
实例的句柄,那么可以预期等式和身份比较都适用于Foo
Python对象(即assert(Foo.get("abc") is Foo.get("abc"))
)。要返回对同一Python对象的引用,需要管理关联的PyObject
。
试试这个:
.def(self == self)
.def(self != self)
参考:http://www.boost.org/doc/libs/1_57_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_operators_special_functions
- C++:从抽象类重写纯虚拟运算符重载
- 重写派生类中的二元运算符
- 将方法委托给成员的重写运算符>
- 通过运算符使用标量参数重写来修改类成员
- 重写自定义数组类的运算符/开始/结束
- 使用空实现重写删除运算符
- 使派生类使用重写运算符
- 试图重写代码以包括模量运算符
- 重写运算符 [] 和调用方法
- 将运算符重写应用于具有动态分配指针的类
- 如何在模板子类中重写转换运算符C++
- 重写运算符的返回类型=
- 重写C++中的类和运算符
- 重写迭代器的运算符*()
- Boost Python重写相等运算符
- 更正重写的QDataStream运算符和链接问题
- 类中调用的重写[]运算符的版本错误
- C++运算符重写
- 堆中的对象和重写索引运算符
- 重写String类中的下标运算符