Как обменять 2 идентификатора объекта в Python? - PullRequest
2 голосов
/ 31 января 2012

У меня есть 2 экземпляра x и y одного класса RBnode.Есть ли способ обмена их идентичностями, чтобы все ссылки на x переходили на y и наоборот?

Например,

x = RBnode()
y = RBnode()
x.data = 1
y.data = 2
L = [x,y]

exchange_identity(x,y)
print x.data, y.data, (L[0] is y)

>>> 2 1 True

На самом деле я строю расширениекрасно-черного дерева.Узлы дерева реализованы как объект.При написании метода удаления узла мне нужно обменяться двумя узлами, чтобы удаляемый узел оказался «внизу» дерева.

Сначала я попытался просто обменяться данными в двух узлах:

def remove_node(self, y):
    ''' remove node y from tree
    return (y.key,y.value) if successful'''
... ... ...

    # exchange y's data with that of its successor y.next 

    y.key = y.next.key
    y.value = y.next.value

Но позже произошла ошибка, когда был вызван remove_node, а функция вызывающей стороны удерживала ссылку на узел x, который оказался y.next.Что-то вроде

x = y.next
self.remove_node(y)
x.parent
>>> AttributeError: 'NoneType' object has no attribute 'parent'

Я мог бы обменять все соответствующие атрибуты x и y.Но это занимает довольно много строк, так как структура узла довольно сложна.

Ответы [ 2 ]

6 голосов
/ 31 января 2012

Я, должно быть, что-то упустил, потому что с этим не так?

>>> class RBnode(object):
...   pass
... 
>>> x = RBnode()
>>> y = RBnode()
>>> id(x), id(y)
(20552592, 20552528)
>>> x,y = y,x
>>> id(x), id(y)
(20552528, 20552592)

Или вы имели в виду переназначение всех имен, что-то вроде кражи личных данных объекта? Хотя было бы возможно работать на уровне C, я был бы весьма удивлен, если бы вы могли делать это изнутри Python, не нарушая при этом ничего.

1 голос
/ 31 января 2012

«Кража личности» невозможна в Python; однако обычно вы можете обменять содержимое двух разных объектов (и, возможно, даже обменять тип на определенные пользователем классы):

>>> n = Node()
>>> o = Node()
>>> p = Node(n, o)
>>> q = Node()
>>> r = Node(p, q)

>>> # swap bodies of p and r
>>> p.left, p.right, r.left, r.right = p.right, p.left, r.right, r.left
...