@Span4ev

Почему не копируется список внутри класса?

Сейчас был удивлён... Не могу скопировать список внутри класса в другой список

class Items:

    def __init__(self):
        self.open_items         = []
        # Я так не делаю. Это просто 3 варианта как я пытался его скопировать
        self.sorted_items       = self.open_items.copy()
        self.sorted_items_2     = self.open_items         
        self.sorted_items_3     = list(self.open_items)
        
item = Items()
item.open_items = ['экземляры класса' ....]

x = item.sorted_items_2

print(x)
---> []


Я создаю экземпляр класса с пустым списком, затем извне пополняю его динамически, но в какой-то момент мне нужно сделать сортировку. Я хочу копировать в sorted_items содержимое списка open_items, но я получаю пустой список. Почему? В экземпляре класса список open_items уже не пустой, но в другой список его содержимое не копируется. Я даже не получаю в sorted_items ссылку на объект open_items
  • Вопрос задан
  • 95 просмотров
Решения вопроса 2
Vindicar
@Vindicar
Запомни одну простую вещь: переменная в питоне - это просто ссылка, ярлык!
Покажу на примере:
a = [1, 2, 3]  # а содержит ссылку на некий список
b = a  # b содержит ссылку на тот же список!
print(b is a)  # True. b - это тот же объект, что и a
a.append(4)  # Ссылка а не меняется, меняется объект по этой ссылке!
print(a)  # [1, 2, 3, 4]
print(b)  # [1, 2, 3, 4] так как b ссылается на то же, что и a
a = [1, 2]  # теперь a хранит ссылку на другой объект-список!
print(b is a)  # False. Даже если бы содержимое списков совпало, это два разных объекта.
print(a)  # [1, 2]
print(b)  # [1, 2, 3, 4] так как b хранит ссылку на старый список
a.append(5)
print(a)  # [1, 2, 5] изменили объект, на который ссылается a
print(b)  # [1, 2, 3, 4] b ссылается на другой объект, он остался не изменён.


Соответственно, у твоей проблемы есть четыре разных решения.
1. Делай копию тогда, когда она тебе понадобится (т.е. тогда, когда в исходном списке уже лежат нужные значения). Не полагайся на то, что две доступные извне переменные всегда будут указывать на один и тот же список.
2а. Не заменяй список на другой. Если ты хочешь заменить именно содержимое списка, а не заменять один объект-список на другой, можно написать так: a[:] = [1, 2, 3, 4] Для надёжности можешь этот список показать как read-only property вместо обычного поля класса - тогда можно будет модифицировать объект списка (добавлять/удалять элементы), но нельзя будет заменить список на другой.
2б. Покажи наружу список как read-write property, при записи в property записывай список в обе переменные.
3. Добавь в класс методы для управления элементами списка, сам список наружу не показывай.
Ответ написан
@o5a
Этим действием
item.open_items = ['item 1', 'item 2']
Вы не добавляете элементы к изначальному списку open_items, а перезаписываете его другим списком (объектом), поэтому ссылающиеся на изначальный список self.sorted_items_2 и т.п. так и остаются ссылаться на изначальный пустой список.
Если бы делали так например
item.open_items.append('item 1')
То и ссылки бы сохранялись.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы