【问题标题】:Object comparison in numba jitclassnumba jitclass 中的对象比较
【发布时间】:2020-08-21 19:19:33
【问题描述】:

如何比较两个 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 似乎有效。但我可以相信它吗?

【问题讨论】:

  • 您能否指定,要如何比较两个对象?比较value 属性的相似度是否足够,还是必须同时比较nextprev
  • 我想比较 nextprev。如果我断言a = b 我希望a == b 评估为True
  • 看看__eq__(self, other)方法here
  • 运行您的代码时,我收到以下警告 @jitclass(DoubleLinkedNode_spec) NumbaDeprecationWarning: The 'numba.jitclass' decorator has moved to 'numba.experimental.jitclass' to better reflect the experimental nature of the functionality. Please update your imports to accommodate this change and see http://numba.pydata.org/numba-doc/latest/reference/deprecation.html#change-of-jitclass-location for the time frame. 似乎 jitclass 不支持类成员,因此定义 __eq__ 不是一个选项,因为它会创建 __hash__,这会出错

标签: python-3.x jit numba


【解决方案1】:

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__,它将根本不起作用。这适用于我迄今为止测试过的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多