Сравнение объектов в numba jitclass - PullRequest
1 голос
/ 06 мая 2020

Как я могу сравнить два объекта numba jitclass, чтобы узнать, одинаковы ли они?

У меня есть следующий код

from numba import jitclass
import numba

node_type = numba.deferred_type()
DoubleLinkedNode_spec = [
  ('value', numba.optional(numba.typeof(1.0))),
  ('prev', numba.optional(node_type)),
  ('next', numba.optional(node_type))
]

@jitclass(DoubleLinkedNode_spec)
class DoubleLinkedNode(object):
  def __init__(self, value, prev, next):
    self.value = value
    self.prev = prev
    self.next = next

node_type.define(DoubleLinkedNode.class_type.instance_type)

n1 = DoubleLinkedNode(1.0, None, None)
n2 = DoubleLinkedNode(2.0, n1, None)
n1.next = n2
print(f'{n2}\n{n2.prev.next}')
#outputs: 
#  <numba.jitclass.boxing.DoubleLinkedNode object at 0x7fbf26923850>
#  <numba.jitclass.boxing.DoubleLinkedNode object at 0x7fbf256b3cf0>
print(f'Next is None. n1: {n1.next is None}   n2: {n2.next is None}')
#outputs: 
#  Next is None. n1: False   n2: True

Это стандартный узел для списка с двойной связью.

Оператор is не работает, так как они находятся в разных адресах памяти.

  1. Почему это происходит?
  2. Как тогда я могу сравнить два объекта?
  3. is None кажется, работает. Но могу ли я ему доверять?

1 Ответ

1 голос
/ 18 мая 2020

методы Dunder не работают должным образом с классами jitclass, поэтому я реализовал нечто похожее на __eq__.

from numba.experimental import jitclass
import numba

node_type = numba.deferred_type()
DoubleLinkedNode_spec = [
    ('value', numba.optional(numba.typeof(1.0))),
    ('prev', numba.optional(node_type)),
    ('next', numba.optional(node_type))
]

@jitclass(DoubleLinkedNode_spec)
class DoubleLinkedNode(object):
    def __init__(self, value, prev, next):
        self.value = value
        self.prev = prev
        self.next = next

    def equal(self, other):
        return self.prevs_eq(other) and self.nexts_eq(other)

    def prevs_eq(self, other):
        while True:
            if self.prev is None:
                return self.value == other.value
            if not self.value == other.value:
                return False

            self = self.prev
            other = other.prev

    def nexts_eq(self, other):
        while True:
            if self.next is None:
                return self.value == other.value
            if not self.value == other.value:
                return False

            self = self.next
            other = other.next

node_type.define(DoubleLinkedNode.class_type.instance_type)

n1 = DoubleLinkedNode(1.0, None, None)
n2 = DoubleLinkedNode(2.0, n1, None)
n1.next = n2

print(f'{n2.equal(n2.prev.next)}')
# True

Вы должны вызвать метод equal, который неэлегантен, но если вы переименуете его в __eq__ это вообще не сработает. Это работает для того, что я тестировал до сих пор.

...