Допустимо ли копирование для назначения списков? - PullRequest
1 голос
/ 04 августа 2020

Рассмотрим следующий минимальный пример:

class MyClass():
    def __init__(self, length):
        self._list = [[] for _ in range(length)]
    def __setitem__(self, key, value):
        self._list[key] = value.copy()
    def __getitem__(self, key):
        return self._list[key]

Теперь в документации Python сказано:

Операторы присваивания в Python не копируют объекты, они создают привязки между целью и объектом.

Применение вышеуказанного класса будет означать что-то вроде:

>>> l = [[1,2,3,4], [3,2,1,0]]
>>> C = MyClass(2)
>>> C[0] = l[0]

Это действительно оператор присваивания. Но теперь значения копируются:

>>> C[0] == l[0]
True
>>> C[0] is l[0]
False

Это приемлемое поведение для класса из Python?

1 Ответ

1 голос
/ 04 августа 2020

В этом нет ничего плохого. Если ваш класс хорошо документирован, если у вас есть веская причина сделать это go для него. Рассмотрим следующий класс из модуля стандартной библиотеки shelve, который по существу предоставляет интерфейс базы данных, подобный dict. Поскольку использование object[key] = value будет записывать на диск, а получение этого объекта будет извлекать его с диска, он не даст вам тот же объект (обязательно, есть варианты кеширования)! Итак:

In [1]: import shelve

In [2]: data = [[1,2,3],[4,5,6]]

In [3]: database = shelve.open('db')

In [4]: database['key'] = data[0]

In [5]: database['key']
Out[5]: [1, 2, 3]

In [6]: database['key'] is data[0]
Out[6]: False

Эта часть документации относится к операторам присваивания переменной, например:

some_var = foo

Где действительно, никогда копий. И вы не можете этого изменить (ну, может быть, но это другой вопрос). Вы можете использовать __setitem__ и __getitem__, но вы можете использовать sh.

...