Если коротко, то типы в Python делятся либо на встроенные и пользовательские, либо на mutable и immutable (сразу так и не подобрал подходящего перевода на русский язык). Ну а если немного подробнее, то как-то так:

Рассмотрим простой пример кода (здесь и далее примеры кода будут писаться и выполняться в ipython’е):

In [1]: a = 1000
In [2]: a
Out[2]: 1000
In [3]: type(a)
Out[3]: int

Здесь мы объявляем переменую создаем объект (object) a, со значением(value) 1000 типа(type) int. Объекты в python - это абстрация над данными. Поэтому любой объект содержит в себе идентификатор(identity), тип и значение. Идентификатор - это адрес объекта в памяти, который никогда не меняется. Но мы можем присвоить объекту новое значение, написав, следующий код:

In [4]: a = 'hello'
In [5]: a
Out[5]: 'hello'
In [6]: type(a)
Out[6]: str

Теперь мы присвоили объекту a новое значение типа string. За кулисами этого всего, интерпритатор сделал, примерно, такое: создал новый объект ‘hello’, и поменялл ссылку переменной a на новый объект в памяти. При этом старое значение 1000 все еще хранится в памяти и будет удалено сборщиком мусора, т.к. на него нет ни одной ссылки. Тоже самое происходит и присвоении переменной нового значений такого же типа:

In [7]: b = 1000
In [8]: id(b)
Out[8]: 40235856
In [9]: b = 1001
In [10]: id(b)
Out[10]: 39189680

Интересный эффект будет при использовании целых чисел в диапазоне от -5, до 256 - их id всегда будет одинаковый, т.к. для улучшения быстродействия интерпритатор при старте создает объекты с этими значениями.

Стандартные типы в CPython делятся на два типа: mutable и immutable. Mutable — это обекты, значения которых могут быть изменены(например, list), а immutable — это обекты, значения которых не может меняться (например, string). Но это не значит, что если у нас есть переменная immutable типа, то ее нельзя изменить. Например, с типом string все привыкли работать так:

In [11]: text = 'Hello'
In [12]: text
Out[12]: 'Hello'
In [13]: text = 'Hello, World'
In [14]: text
Out[14]: 'Hello, World'

Как мы видим, начение переменной text поменялось. На самом деле, при присвоении переменной text нового значения, в памяти создается новый объект, и переменная text начинает на него ссылаться. В этом легко убедится при помощи функции id - получить идентификатор до и после изменения переменной.

Mutable типы ведут себя так:
In [15]: l = [1, 2, 3]
In [16]: l
Out[16]: [1, 2, 3]
In [17]: id(l)
Out[17]: 139901299808088
In [18]: l.append(4)
In [19]: l
Out[19]: [1, 2, 3, 4]
In [20]: id(l)
Out[20]: 139901299808088

Основываясь на этом свойстве(и не только), ключами в словаре (dict) могут быть только immutable обекты:

In [21]: d = {'one': 1}
In [22]: type(d)
Out[22]: dict
In [23]: d[1]=1
In [24]: d
Out[24]: {1: 1, 'one': 1}
In [25]: d[l] = 'list'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-4f49b18d7af7> in <module>() ----> 1 d[l] = 'list'
TypeError: unhashable type: 'list'

Immutable типы в Python — это числа(numbers), строки (strings) и кортежи (tuples).

Для облегчения привжу список некоторых всторенных типов (built-in types):

 

  • Numbers (числа) — int, long, float, complex(3+4j), Decimal, Fraction
  • Sequence Types (последовательности) — str, unicode, list, tuple, bytearray, buffer, xrange
  • Sets — set, frozenset
  • Maps (хеш-таблицы) — dict
  • Files, context managers и другие.

 

Ссылки по теме:

 

 

 


Comments

dluciv Russia

Saturday, January 11, 2014 9:21 AM

dluciv

Возможно вместе с упоминанием str  и unicode стоило написать в скобках соответствующие типы для третьего Питона. А то явно про версию не сказано вообще ничего...

Istergul Russia

Saturday, January 11, 2014 10:32 AM

Istergul

mutable - изменяемые, immutable - неизменяемые.

gigimon United States

Saturday, January 11, 2014 7:10 PM

gigimon

Не соглашусь с фразой: "Immutable типы в Python — это числа(numbers), строки (strings) и кортежи (tuples).". Ключами в словаре могут быть hashable объекты и к их изменяемости это отношение не имеет.
In [1]: class A(object):
   ...:     def __hash__(self):
   ...:         return 123
   ...:    

In [2]: a = A()

In [3]: b = {}

In [4]: b[a] = 'sdasd'

In [5]: b
Out[5]: {<__main__.A at 0x10a3c1790>: 'sdasd'}

класс вполне себе mutable объект

gigimon United States

Saturday, January 11, 2014 7:11 PM

gigimon

Тьфу, фраза имелась ввиду эта "Основываясь на этом свойстве(и не только), ключами в словаре (dict) могут быть только immutable обекты:"

e0ne United States

Sunday, January 12, 2014 2:46 PM

e0ne

@Istergul, mutable/inmutable и changeable/unchangeable = трудности переводаFrown

e0ne United States

Sunday, January 12, 2014 2:48 PM

e0ne

@gigimon, не нужно путать mutable и hashable.  Не любой hashable объект может быть ключем в словаре

Torwald Russia

Monday, January 13, 2014 5:40 AM

Torwald

> Основываясь на этом свойстве(и не только), ключами в словаре (dict) могут быть только immutable обекты

> TypeError: unhashable type: 'list'

Ключами словаря, судя по этой ошибке не могут быть нехэшируемые типы данных. Изменяемость-неизменяемость тут роли не играет.

In [31]: class MyList(list):
   ....:     def __hash__(self):
   ....:         return id(self)
   ....:    

In [32]: t = MyList('set')

In [33]: t
Out[33]: ['s', 'e', 't']

In [34]: t.__hash__()
Out[34]: 42579408

In [35]: t.__hash__()
Out[35]: 42579408

In [36]: t2 = MyList('foo')

In [37]: t2.__hash__()
Out[37]: 42580112

In [38]: d = {t: 1, t2: 2}

In [39]: d
Out[39]: {['f', 'o', 'o']: 2, ['s', 'e', 't']: 1}

In [40]: d[t]
Out[40]: 1

In [41]: d[t] = 12

e0ne United States

Tuesday, January 14, 2014 1:26 PM

e0ne

Процитирую http://docs.python.org/2/reference/datamodel.html:
"An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable."
и
"Some objects contain references to other objects; these are called containers. Examples of containers are tuples, lists and dictionaries. The references are part of a container’s value. In most cases, when we talk about the value of a container, we imply the values, not the identities of the contained objects; however, when we talk about the mutability of a container, only the identities of the immediately contained objects are implied. So, if an immutable container (like a tuple) contains a reference to a mutable object, its value changes if that mutable object is changed."

Torwald Russia

Friday, January 17, 2014 8:04 AM

Torwald

Я про изменяемость в курсе. Я лишь хотел сказать, что ключом словаря может быть как изменяемый (mutable), так и не изменяемый (immutable) объект. Основное требование к ключу словаря - это hashable. Он может быть как mutable, так и immutable.
Цитата из docs.python.org/2.7/library/stdtypes.html#dict
"Values that are not hashable, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys."
hashable: docs.python.org/2.7/glossary.html#term-hashable
"All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal (except with themselves), and their hash value is their id()."

Я лишь хочу сказать, что фразу "Основываясь на этом свойстве(и не только), ключами в словаре (dict) могут быть только immutable обекты" следует изменить на более конкретную, применительно к встроенным типам, "Ключами словаря dict не могут быть builtin mutable объекты". В данном случае, builtin mutable являются лишь частным случаем unhashable типов.

Comments are closed