Считается ли это неизменяемым из-за структуры / иерархии класса?, что означает float находится наверху класса и является вызовом его собственного метода. Аналогично примеру этого типа (хотя в моей книге сказано, что dict является изменяемым):
Также, в качестве последнего class(SortedKeyDict_a), если я передам ему этот тип set:
d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))
без вызова example метода он возвращает словарь. SortedKeyDict With __new__ помечает это как ошибку. Я попробовал передать целые числа в RoundFloat класс с помощью __new__, и он не выдал ошибок.
Переведено автоматически
Ответ 1
Что? Значения с плавающей точкой неизменяемы? Но я не могу сделать
x = 5.0 x += 7.0 print x # 12.0
Разве это не "мутирует" x?
Ну, вы согласны, что строки неизменяемы, верно? Но вы можете сделать то же самое.
s = 'foo' s += 'bar' print s # foobar
Значение переменной меняется, но оно меняется за счет изменения того, на что ссылается переменная. Изменяемый тип может изменяться таким образом, и он может также изменяться "на месте".
Вот в чем разница.
x = something # immutable type print x func(x) print x # prints the same thing
x = something # mutable type print x func(x) print x # might print something different
x = something # immutable type y = x print x # some statement that operates on y print x # prints the same thing
x = something # mutable type y = x print x # some statement that operates on y print x # might print something different
Конкретные примеры
x = 'foo' y = x print x # foo y += 'bar' print x # foo
x = [1, 2, 3] y = x print x # [1, 2, 3] y += [3, 2, 1] print x # [1, 2, 3, 3, 2, 1]
deffunc(val): val += 'bar'
x = 'foo' print x # foo func(x) print x # foo
deffunc(val): val += [3, 2, 1]
x = [1, 2, 3] print x # [1, 2, 3] func(x) print x # [1, 2, 3, 3, 2, 1]
Ответ 2
Вы должны понимать, что Python представляет все свои данные в виде объектов. Некоторые из этих объектов, такие как списки и словари, изменяемы, что означает, что вы можете изменять их содержимое, не меняя их идентификатора. Другие объекты, такие как целые числа, числа с плавающей запятой, строки и кортежи, являются объектами, которые нельзя изменить. Простой способ понять это, взглянув на идентификатор объекта.
Ниже вы видите строку, которая является неизменяемой. Вы не можете изменить ее содержимое. При попытке изменить ее будет вызвано TypeError. Кроме того, если мы назначаем новое содержимое, вместо изменяемого содержимого создается новый объект.
>>> s = "abc" >>> id(s) 4702124 >>> s[0] 'a' >>> s[0] = "o" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str'object does not support item assignment >>> s = "xyz" >>> id(s) 4800100 >>> s += "uvw" >>> id(s) 4800500
Вы можете сделать это со списком, и это не изменит идентичность объектов
Один из способов быстро проверить, является ли тип изменяемым или нет, заключается в использовании id() встроенной функции.
Примеры использования для целых чисел,
>>> i = 1 >>> id(i) ***704 >>> i += 1 >>> i 2 >>> id(i) ***736 (different from ***704)
использование списка on,
>>> a = [1] >>> id(a) ***416 >>> a.append(2) >>> a [1, 2] >>> id(a) ***416 (same with the above id)
Ответ 4
Прежде всего, имеет ли класс методы или какова его структура класса, не имеет ничего общего с изменчивостью.
ints и floats являются неизменяемыми. Если я сделаю
a = 1 a += 5
Он указывает имя a на 1 где-то в памяти в первой строке. Во второй строке он ищет это 1, добавляет 5, получает 6, затем указывает a на это 6 в памяти - это никоим образом не изменило1 на 6. Та же логика применима к следующим примерам, с использованием других неизменяемых типов:
b = 'some string' b += 'some other string' c = ('some', 'tuple') c += ('some', 'other', 'tuple')
Для изменяемых типов я могу сделать то, что фактически изменяет значение, в котором оно хранится в памяти. С помощью:
d = [1, 2, 3]
Я создал список местоположений 1, 2 и 3 в памяти. Если я затем сделаю
e = d
Я просто указываю e на те же listd точки в. Затем я могу сделать:
e += [4, 5]
И список, на который указывают оба e и d, будет обновлен, чтобы также содержать местоположения 4 и 5 в памяти.
Если я вернусь к неизменяемому типу и сделаю это с помощью tuple:
f = (1, 2, 3) g = f g += (4, 5)
Тогда f все еще указывает только на оригинал tuple - вы указали g на совершенно новый tuple.
d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))
(который является tuple из tuples) как val, вы получаете ошибку, потому что у tuples нет .clear() метода - вам нужно было бы передать dict(d) как val, чтобы он заработал, и в этом случае вы получите пустое значение SortedKeyDict в результате.