Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two ctypes objects for equality?

Tags:

python

ctypes

import ctypes as ct

class Point(ct.Structure):
    _fields_ = [
        ('x', ct.c_int),
        ('y', ct.c_int),
    ]

p1 = Point(10, 10)
p2 = Point(10, 10)

print p1 == p2 # => False

The equality operator '==' gives False in the trivial case above. Is there any straightforward approach?

EDIT:

Here's a slightly improved version (based on the accepted answer), which can also deal with nested arrays:

import ctypes as ct

class CtStruct(ct.Structure):

    def __eq__(self, other):
        for field in self._fields_:
            attr_name = field[0]
            a, b = getattr(self, attr_name), getattr(other, attr_name)
            is_array = isinstance(a, ct.Array)
            if is_array and a[:] != b[:] or not is_array and a != b:
                return False
        return True

    def __ne__(self, other):
        for field in self._fields_:
            attr_name = field[0]
            a, b = getattr(self, attr_name), getattr(other, attr_name)
            is_array = isinstance(a, ct.Array)
            if is_array and a[:] != b[:] or not is_array and a != b:
                return True
        return False

class Point(CtStruct):
    _fields_ = [
        ('x', ct.c_int),
        ('y', ct.c_int),
        ('arr', ct.c_int * 2),
    ]

p1 = Point(10, 20, (30, 40))
p2 = Point(10, 20, (30, 40))

print p1 == p2 # True
like image 269
FipS Avatar asked Jun 19 '14 12:06

FipS


People also ask

How do you compare two objects in the same class in Python?

The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory. In the vast majority of cases, this means you should use the equality operators == and !=

What is ctypes CDLL?

ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

Does ctypes work with C++?

ctypes is the de facto standard library for interfacing with C/C++ from CPython, and it provides not only full access to the native C interface of most major operating systems (e.g., kernel32 on Windows, or libc on *nix), but also provides support for loading and interfacing with dynamic libraries, such as DLLs or ...

Could not find a version that satisfies the requirement ctypes from versions?

Try uninstalling, your current installation, download it (again) from the site and try reinstalling.


2 Answers

Create a class MyCtStructure, then all its subclass don't need to implement __eq__ & __ne__. Defining eq wouldn't be a bit tedious job in your case anymore.

import ctypes as ct
class MyCtStructure(ct.Structure):

    def __eq__(self, other):
        for fld in self._fields_:
            if getattr(self, fld[0]) != getattr(other, fld[0]):
                return False
        return True

    def __ne__(self, other):
        for fld in self._fields_:
            if getattr(self, fld[0]) != getattr(other, fld[0]):
                return True
        return False

class Point(MyCtStructure):
    _fields_ = [
        ('x', ct.c_int),
        ('y', ct.c_int),
    ]


p1 = Point(10, 11)
p2 = Point(10, 11)

print p1 == p2
like image 199
bpceee Avatar answered Oct 20 '22 00:10

bpceee


p1.x == p2.x and p1.y = p2.y will work in this trivial case.

You could also implement the __eq__() an __ne__() methods in your Point class:

class Point(ct.Structure):
    _fields_ = [
        ('x', ct.c_int),
        ('y', ct.c_int),
    ]
    def __eq__(self, other):
        return (self.x == other.x) and (self.y == other.y)
    def __ne__(self, other):
        return not self.__eq__(other)

>>> p1 = Point(10, 10)
>>> p2 = Point(10, 10)
>>> p3 = Point(10, 66)
>>> p1 == p2
True
>>> p1 != p2
False
>>> p1 == p3
False
>>> p1 != p3
True
like image 37
mhawke Avatar answered Oct 19 '22 22:10

mhawke