Неизменяемые и изменчивые типы - PullRequest
168 голосов
/ 08 ноября 2011

Я не совсем понимаю, что такое неизменный тип. Я знаю, что объект float считается неизменным, например, из моей книги:

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2))

Считается ли это неизменным из-за структуры / иерархии классов? То есть float находится наверху класса и является его собственным вызовом метода. Подобно этому типу примера (хотя моя книга говорит, что dict изменчива):

class SortedKeyDict(dict):
    def __new__(cls, val):
        return dict.__new__(cls, val.clear())

В то время как что-то непостоянное имеет методы внутри класса, с примером такого типа:

class SortedKeyDict_a(dict):
    def example(self):
        return self.keys()

Кроме того, за последние class(SortedKeyDict_a), если я передам ему этот тип набора:

d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))

без вызова метода example возвращает словарь. SortedKeyDict с __new__ помечает это как ошибку. Я попытался передать целые числа в класс RoundFloat с помощью __new__, и он не пометил ошибки.

Ответы [ 16 ]

4 голосов
/ 24 июня 2016

Мне кажется, вы боретесь с вопросом, что на самом деле означает изменчивое / неизменяемое .Итак, вот простое объяснение:

Во-первых, нам нужен фундамент, на котором будет основано объяснение.

Так что думайте обо всем, что вы программируете как виртуальный объект, что-то, чтосохраняется в памяти компьютера как последовательность двоичных чисел.(Однако не пытайтесь представить это слишком сложно. ^^) Теперь на большинстве компьютерных языков вы не будете работать с этими двоичными числами напрямую, а скорее будете использовать интерпретацию двоичных чисел.

Например, выне думайте о числах, таких как 0x110, 0xaf0278297319 или аналогичных, но вместо этого вы думаете о числах, таких как 6, или строках, таких как «Hello, world».Тем не менее эти числа или строки являются интерпретацией двоичного числа в памяти компьютера.То же самое верно для любого значения переменной.

Короче говоря: Мы не программируем с фактическими значениями, но с интерпретациями фактическогодвоичные значения.

Теперь у нас есть интерпретации, которые не должны изменяться ради логики и других «изящных вещей», в то время как есть интерпретации, которые вполне могут быть изменены.Например, представьте себе симуляцию города, другими словами, программу, в которой много виртуальных объектов, а некоторые из них - дома.Теперь можно ли изменить эти виртуальные объекты (дома) и можно ли считать их одними и теми же домами?Ну, конечно, они могут.Таким образом, они являются изменяемыми: их можно изменять, не становясь «совершенно» другим объектом.

Теперь подумайте о целых числах: это также виртуальные объекты (последовательности двоичных чисел в памяти компьютера).Итак, если мы изменим один из них, например, увеличив значение шесть на одно, это все равно шесть?Ну, конечно, нет.Таким образом, любое целое число является неизменным.

Итак: Если любое изменение в виртуальном объекте означает, что оно фактически становится другим виртуальным объектом, то оно называется неизменным.

Заключительные замечания:

(1) Никогда не путайте свой реальный опыт изменчивости и неизменяемости с программированием на определенном языке:

Каждый язык программированияимеет собственное определение того, какие объекты могут быть приглушены, а какие нет.

Так что, хотя теперь вы можете понять разницу в значении, вам все равно придется изучить фактическую реализацию длякаждый язык программирования.... Действительно, может быть цель языка, где 6 может быть приглушен, чтобы стать 7. С другой стороны, это может быть довольно сумасшедший или интересный материал, например симуляции параллельных вселенных. ^^

(2) Это объяснение не является научным, оно призвано помочь вам понять разницу между изменчивым и неизменным.

3 голосов
/ 04 января 2013

Один способ думать о разнице:

Назначения неизменяемых объектов в python можно рассматривать как глубокие копии, тогда как присвоения изменчивым объектам поверхностны

2 голосов
/ 02 февраля 2017

Самый простой ответ:

Изменяемая переменная - это переменная, значение которой может измениться на месте, тогда как в неизменяемой переменной изменение значения не произойдет на месте.Изменение неизменяемой переменной перестроит ту же самую переменную.

Пример:

>>>x = 5

Создает значение 5, на которое ссылается x

x ->5

>>>y = x

Это утверждение заставит y ссылаться на 5 из x

x -------------> 5 <----------- y </p>

>>>x = x + y

Поскольку x является целым числом (неизменяемого типа), было перестроено.

В выражении выражение RHS приведет к значению 10, а когда этоназначенный на LHS (x), x восстановит до 10. Так что теперь

x ---------> 10

y --------->5

0 голосов
/ 31 декабря 2018

Для неизменяемых объектов присваивание создает новую копию значений, например.

x=7
y=x
print(x,y)
x=10 # so for immutable objects this creates a new copy so that it doesnot 
#effect the value of y
print(x,y)

Для изменяемых объектов назначение не создает другую копию значений. Например,

x=[1,2,3,4]
print(x)
y=x #for immutable objects assignment doesn't create new copy 
x[2]=5
print(x,y) # both x&y holds the same list
0 голосов
/ 05 июля 2017

Я не прочитал все ответы, но выбранный ответ не является правильным, и я думаю, что у автора есть идея, что возможность переназначения переменной означает, что любой тип данных является изменяемым.Это не относится к делу.Изменчивость связана с передачей по ссылке, а не передачей по значению.

Допустим, вы создали список

a = [1,2]

Если бы вы сказали:

b = a
b[1] = 3

Даже если вы переназначили значение для B, оно также переназначит значение для a.Это потому, что когда вы назначаете "b = a".Вы передаете «Ссылку» объекту, а не копию значения.Это не относится к строкам, числам с плавающей запятой и т. Д. Это делает изменяемым список, словари и подобные записи, но логические значения, значения с плавающей запятой и т. Д. Неизменяемыми.

0 голосов
/ 03 июля 2016

В Python есть простой способ узнать:

Неизменный:

    >>> s='asd'
    >>> s is 'asd'
    True
    >>> s=None
    >>> s is None
    True
    >>> s=123
    >>> s is 123
    True

Изменяемый:

>>> s={}
>>> s is {}
False
>>> {} is {}
Flase
>>> s=[1,2]
>>> s is [1,2]
False
>>> s=(1,2)
>>> s is (1,2)
False

И:

>>> s=abs
>>> s is abs
True

Так что я думаю, что встроенная функция также неизменна в Python.

Но я действительно не понимаю, как работает float:

>>> s=12.3
>>> s is 12.3
False
>>> 12.3 is 12.3
True
>>> s == 12.3
True
>>> id(12.3)
140241478380112
>>> id(s)
140241478380256
>>> s=12.3
>>> id(s)
140241478380112
>>> id(12.3)
140241478380256
>>> id(12.3)
140241478380256

Это так странно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...