Я новичок в Python (с C++) и понимаю, что, грубо говоря, все переменные (имена) являются ссылками на объекты Python. Некоторые из этих объектов изменяемы (списки), а другие нет (кортежи, хотя вы можете изменить их элементы, если они сами изменяемы).
Для изменяемых объектов я могу изменить их, обратившись к их функциям-модификаторам (таким как .append()
) через имена, к которым они привязаны. Например:
myList = [1,2,3,4]
myList.append(5)
Однако я знаю, что простое присвоение myList
второму списку просто создает экземпляр этого второго списка и переназначает ему myList
; Исходный список [1,2,3,4]
все еще существует, пока сборщик мусора не очистит его (или не очистит, если ему будет присвоено другое имя).
МОЙ ВОПРОС:
Допустим, у меня есть класс Point
:
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
p1 = Point(1,1)
p1.x = 2
p1.y = 2
Как заменить p1.x = 2
и p1.y = 2
одной командой, которая просто присваивает мой объект Point(1,1)
объекту Point(2,2)
? Очевидно, что p1 = Point(2,2)
не работает, так как это просто переназначает имя p1 новому и другому объекту Point(2,2)
(а это не то, что мне нужно!).
Есть ли встроенный способ сделать это или мне нужно определить дополнительную функцию модификатора в Point
:
def changePoint(self, newPoint):
self.x = newPoint.x
self.y = newPoint.y
чтобы сделать это одной командой (т.е. через p1.changePoint(Point(2,2))
)? В C++ вы часто можете просто использовать неявно определенный перегруженный оператор присваивания класса (operator=
) и выполнить это в одной команде:
SimpleNameClass* objectPtr = new SimpleNameClass("Bob");
//Dereferencing objectPtr and assigning new object:
*objectPtr = SimpleNameClass("Jim");
//Now objectPtr still points to (references) the same address in memory,
//but the underlying object is completely different.
В целом кажется утомительным изменять каждый атрибут по отдельности, когда я хочу преобразовать свой объект в новый, особенно если мой объект содержит много атрибутов!
ИЗМЕНИТЬ:
В дополнение к ответу Джайнила оказывается, что мне даже не нужно менять определение init, я могу просто использовать приведенную выше версию. Затем вы можете преобразовать объект Point в другой с помощью одной команды, например:
p1.__init__(2,2) #Replaces p1.x = 2, p1.y = 2
Это работает, так как исходная инициализация занимает 2 аргумента. Таким образом, стандартный ванильный метод инициализации в основном уже позволяет изменять базовый объект в дополнение к его созданию (по крайней мере, в этом случае). Ура.