了解此示例代码中 ctypes 模块的用法



上下文:
我发现了一些实现XOR链表的代码。在XOR链表中,不是每个节点都有下一个指针,而是有一个both属性,该属性是前一个节点和下一个节点的XOR。

import ctypes

# This is hacky. It's a data structure for C, not python.
class Node(object):
def __init__(self, val):
self.val = val
self.both = 0

class XorLinkedList(object):
def __init__(self):
self.head = self.tail = None
self.__nodes = [] # This is to prevent garbage collection
def add(self, node):
if self.head is None:
self.head = self.tail = node
else:
self.tail.both = id(node) ^ self.tail.both
node.both = id(self.tail)
self.tail = node
# Without this line, Python thinks there is no way to reach nodes between
# head and tail.
self.__nodes.append(node)

def get(self, index):
prev_id = 0
node = self.head
for i in range(index):
next_id = prev_id ^ node.both
if next_id:
prev_id = id(node)
node = _get_obj(next_id)
else:
raise IndexError('Linked list index out of range')
return node

def _get_obj(id):
return ctypes.cast(id, ctypes.py_object).value

问题:

  1. 不理解_get_obj()函数的需求及其尝试在这里做什么
  2. self.__nodes = []有什么用处?以及它是如何实现的垃圾收集在这里
  3. 我不知道下面的代码在做什么:

    # Without this line, Python thinks there is no way to reach nodes between
    # head and tail.
    self.__nodes.append(node)`
    

我可以回答您问题中的大部分子问题。

  1. _get_obj()函数是Python自己的id()函数(无论如何都有CPython解释器(。还有其他方法可以做到这一点。例如,请参阅问题是否可以取消引用变量id?。

  2. &3.self.__nodes.append(node)Node实例添加到私有列表中,因为将其添加到XOR链表中不会像在更常见的正常实现中可能发生的那样创建对它的引用(XOR技巧消除了对它们的需要(。如果没有这一点,Python垃圾收集器可能会在Node实例仍然是链表的一部分时将其删除。

相关内容

  • 没有找到相关文章

最新更新