Вопросы о UserList __init__, ([:], isinstance) - PullRequest
0 голосов
/ 07 ноября 2018

Я хотел расширить список классов в python37 с помощью некоторых пользовательских методов. и в итоге прочитал код UserList cpython . После прочтения возникли новые вопросы по поводу использования [:].

Если я правильно понимаю, `[:]` делает фрагментную копию всего `Self.data`. Но я пытаюсь понять, какой смысл использовать `[:]` в левой части оператора `=`.

Есть ли разница между первым и вторым вариантом? Попробовал в питоне переводчик, и оба, кажется, имеют одинаковый эффект, я скучаю что-то?

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# option (1)
letters[:] = []
# option (2)
letters = []

Теперь мои вопросы касаются кода UserList. Я добавил комментарии с вопросами, которые у меня есть.

class UserList(_collections_abc.MutableSequence):
    def __init__(self, initlist=None):
        self.data = []
        if initlist is not None:
            if type(initlist) == type(self.data):
            # NOTE: Is this if statement doing the same?
            # if isinstance(initlist, list):
                self.data[:] = initlist
                # NOTE: wouldn't in this case self.data keep a reference to initlist
                # instead of a copy?
                # self.data[:] = initlist[:]  # could one replace that line with this one?
            elif isinstance(initlist, UserList):
                self.data[:] = initlist.data[:]
                # NOTE: would this line accomplish the same?
                # self.data = initlist.data[:]
            else:
                self.data = list(initlist)
    ...

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Они не ведут себя одинаково, если у вас есть другая ссылка на letters.

Сценарий 1: изменение letters на месте.

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters[:] = []
>>> letters
>>> []
>>> lst
>>> []

Сценарий 2, переназначение имени letters на пустой список.

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> lst = letters
>>> letters = []
>>> letters
>>> []
>>> lst
>>> ['a', 'b', 'c', 'd', 'e', 'f', 'g']

Поскольку имена переназначаются независимо , lst не видит никаких изменений.

Если бы у вас было

self.data = initlist

мутации в initlist будут влиять на self.data (поскольку они являются одним и тем же объектом в памяти).

0 голосов
/ 07 ноября 2018

Когда вы указываете в левой части оператора =, вы используете обычное назначение Python, которое меняет имя a в текущем контексте, чтобы указывать на новое значение. Это не меняет предыдущее значение, на которое указывал a.

Указав [0: 2] в левой части оператора =, вы сообщаете Python, что хотите использовать Slice Assignment. Назначение фрагментов - это специальный синтаксис для списков, в который можно вставлять, удалять или заменять содержимое из списка. См .: Как работает назначение со срезом списка Python

Может быть, это вам поможет.

...