Автор оригинала: Omer Rosenbaum.
Python – это удивительный язык. Из-за его простоты многие люди выбирают его как их первый язык программирования.
Опытные программисты также используют Python все время, благодаря своему широкому сообществу, изобилия пакетов и прозрачного синтаксиса.
Но есть один вопрос, который, кажется, запутает новичков, а также некоторые опытные разработчики: объекты Python. В частности, разница между Meatable и неизменный объекты.
В этом посте мы будем углубить наши знания о объектах Python, изучать разницу между Meatable и неизменный Объекты и посмотрите, как мы можем использовать Переводчик Чтобы лучше понять, как работает Python.
Мы будем использовать важные функции и ключевые слова, такие как ID
и это
и мы поймем разницу между х
и х это y
Отказ
Вы за это? Давайте начнем.
В отличие от других языков программирования, где язык Поддерживает Объекты, в Python действительно все это объект, в том числе целые числа, списки и даже функции.
Мы можем использовать наш переводчик для проверки того, что:
>>> isinstance(1, object) True >>> isinstance(False, object) True def my_func(): return "hello" >>> isinstance(my_func, object) True
У Python есть встроенная функция, ID
, который возвращает адрес объекта в память. Например:
>>> x = 1 >>> id(x) 1470416816
Выше мы создали объект по имени х
и назначил его значение 1
Отказ Затем мы использовали ID (X)
и обнаружил, что этот объект найден по адресу 1470416816
в памяти.
Это позволяет нам проверить интересные вещи о Python. Допустим, мы создадим две переменные в Python – один по имени х
и один по имени y
– и назначьте им одинаковое значение. Например, здесь:
>>> x = "I love Python!" >>> y = "I love Python!"
Мы можем использовать оператор равенства ( ==
), чтобы убедиться, что они действительно имеют одинаковое значение в глазах Python:
>>> x == y True
Но эти тот же объект в памяти? Теоретически, здесь могут быть два очень разных сценария.
Согласно сценарию (1) У нас действительно есть два разных объекта, один по имени х
и другой по имени y
, что просто имеет одинаковое значение.
Тем не менее, это также может быть так, что Python фактически хранит здесь только один объект, который имеет два имена, которые ссылаются на него – как показано в сценарии (2) :
Мы можем использовать ID
Функция, представленная выше, чтобы проверить это:
>>> x = "I love Python!" >>> y = "I love Python!" >>> x == y True >>> id(x) 52889984 >>> id(y) 52889384
Так как мы можем видеть, поведение Python соответствует сценарию (1), описанному выше. Хотя …| х В этом примере (то есть
x и
y имеют одинаковые
ценности ), они разные объекты в памяти. Это потому, что ID (X) (Y) , как мы можем проверить явно:
>>> id(x) == id(y) False
Существует более короткий способ составить сравнение выше, и это использовать Python это
оператор. Проверка ли х это y
такой же, как проверять ID (X) (Y)
, что означает ли х
и y
Тот же объект в памяти:
>>> x == y True >>> id(x) == id(y) False >>> x is y False
Это проливает свет на важное различие между оператором равенства ==
и оператор идентичности это
Отказ
Как вы можете видеть в примере выше, он полностью возможен для двух имен в Python ( x
и y
), чтобы быть связаны с двумя разными объектами (и, таким образом, x y y
False
), где эти два объекта имеют одинаковое значение (так что x
это True
).
Как мы можем создать другую переменную, которая указывает на тот же объект, что х
указывает на? Мы можем просто использовать оператор назначения =
, вот так:
>>> x = "I love Python!" >>> z = x
Чтобы убедиться, что они действительно указывают на тот же объект, мы можем использовать это
Оператор:
>>> x is z True
Конечно, это означает, что у них есть тот же адрес в памяти, так как мы можем проверить явно, используя ID
:
>>> id(x) 54221824 >>> id(z) 54221824
И, конечно, у них такое же значение, поэтому мы ожидаем х
вернуть Правда
также:
>>> x == z True
Мы сказали, что все в Python – это объект, но между объектами существует важное различие. Некоторые объекты являются Meatable Пока некоторые из них неизменный Отказ
Как я уже упоминал ранее, этот факт вызывает путаницу для многих людей, которые новые для Python, поэтому мы собираемся убедиться, что это ясно.
Неизменные объекты в Python
Для некоторых типов в Python, как только мы создали экземпляры этих типов, они никогда не меняются. Они неизменный Отказ
Например, int
Объекты неизменяются в Python. Что произойдет, если мы попытаемся изменить значение int
объект?
>>> x = 24601 >>> x 24601 >>> x = 24602 >>> x 24602
Ну, кажется, что мы изменили х
успешно. Это именно там, где многие люди запутались. Что именно произошло под капотом здесь? Давайте использовать ID
Для дальнейшего расследования:
>>> x = 24601 >>> x 24601 >>> id(x) 1470416816 >>> x = 24602 >>> x 24602 >>> id(x) 1470416832
Так что мы можем видеть, что, присвоение х
мы не изменили значение объекта, что х
был обязан раньше. Скорее, мы создали новый объект и связали имя х
к этому.
Так что после назначения 24601
к х
Используя х
У нас было следующее государство:
И после использования х
Мы создали новый объект и связали имя х
к этому новому объекту. Другой объект со значением 24601
больше не доходит до х
(или любое другое имя в этом случае):
Всякий раз, когда мы назначаем новое значение имени (в приведенном выше примере – x
), который связан с int
Объект, мы фактически изменим связывание этого имени другому объекту.
То же самое относится к кортеж
S, строки ( стр.
объекты), а Bool
S, а также. Другими словами, int
(и другие типы номеров, такие как Float
), кортеж
, Bool
и утра
Объекты – это неизменный Отказ
Давайте проверим эту гипотезу. Что произойдет, если мы создадим кортеж
Объект, а затем дайте ему другое значение?
>>> my_tuple = (1, 2, 3) >>> id(my_tuple) 54263304 >>> my_tuple = (3, 4, 5) >>> id(my_tuple) 56898184
Как и int
Объект, мы видим, что наше назначение фактически изменило объект, которое название my_tuple
связан с.
Что произойдет, если мы попытаемся изменить один из кортеж
элементы?
>>> my_tuple[0] = 'a new value' Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment
Как мы видим, Python не позволяет нам модифицировать my_tuple
Содержание, как это неизменно.
Музные объекты в Python
Некоторые типы в Python могут быть изменены после создания, и они называются Meatable Отказ Например, мы знаем, что мы можем изменить содержимое a Список
объект:
>>> my_list = [1, 2, 3] >>> my_list[0] = 'a new value' >>> my_list ['a new value', 2, 3]
Значит ли это, что мы на самом деле создали новый объект при назначении нового значения первого элемента my_list
? Опять же, мы можем использовать ID
проверить:
>>> my_list = [1, 2, 3] >>> id(my_list) 55834760 >>> my_list [1, 2, 3] >>> my_list[0] = 'a new value' >>> id(my_list) 55834760 >>> my_list ['a new value', 2, 3]
Так что наше первое назначение my_list = [1, 2, 3]
создал объект по адресу 55834760
, со значениями 1
, 2
и 3
:
Затем мы изменили первый элемент этого Список
Объект, использующий my_list [0]
то есть – без создания нового Список
объект:
Теперь давайте создадим два имени – х
и y
, оба связаны с той же Список
объект. Мы можем проверить, что используя это
или явно проверяя их ID
S:
>>> x = y = [1, 2] >>> x is y True >>> id(x) 18349096 >>> id(y) 18349096 >>> id(x) == id(y) True
Что происходит сейчас, если мы используем x.append (3)
? То есть, если мы добавим новый элемент ( 3
) к объекту по имени х
?
Будет ли х
Изменено? Будет ли y
?
Ну, как мы уже знаем, они в основном два имена того же объекта:
Поскольку этот объект изменен, когда мы проверяем его имена, мы можем увидеть новое значение:
>>> x.append(3) >>> x [1, 2, 3] >>> y [1, 2, 3]
Обратите внимание, что х
и y
иметь то же самое ID
Как и раньше – как они все еще связаны с тем же Список
объект:
>>> id(x) 18349096 >>> id(y) 18349096
В дополнение к Список
S, другие типы Python, которые являются Musable, включают Установить
S и Диктовать
с.
Словари ( Dict
Объекты) обычно используются в Python. В качестве быстрого напоминания мы определяем их так:
my_dict = {"name": "Omer", "number_of_pets": 1}
Затем мы можем получить доступ к конкретному элементу его ключевым именем:
>>> my_dict["name"] 'Omer'
Словари Meatable Итак, мы можем изменить их контент после создания. В любой момент, в любой момент, ключ в словаре может указывать только на один элемент:
>>> my_dict["name"] = "John" >>> my_dict["name"] 'John'
Интересно отметить, что Ключи словаря должны быть неизменными :
>>> my_dict = {[1,2]: "Hello"} Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list'
Почему это так?
Рассмотрим следующий гипотетический сценарий (Примечание: фрагмент ниже не может быть запущен в Python):
>>> x = [1, 2] >>> y = [1, 2, 3] >>> my_dict = {x: 'a', y: 'b'}
До сих пор все не кажется плохой. Мы предполагаем, что если мы доступм my_dict
С ключом [1, 2]
мы получим соответствующее значение «А»
и если мы доступ к ключу [1, 2, 3]
мы получим ценность 'b'
Отказ
Теперь, что бы произошло, если мы попытаемся использовать:
>>> x.append(3)
В этом случае х
будет иметь значение [1, 2, 3]
и y
также будет иметь значение [1, 2, 3]
Отказ Что мы должны получить, когда мы просим my_dict [[1, 2, 3]]
? Будет ли это «А»
или 'b'
? Чтобы избежать таких случаев, Python просто не позволяет смешивать ключи словаря.
Давайте попробуем применить наши знания в случае, который немного интереснее.
Ниже мы определяем Список
(A Metable объект) и A кортеж
(AN Immutable объект). Список
включает в себя кортеж
и кортеж
включает в себя Список
:
>>> my_list = [(1, 1), 2, 3] >>> my_tuple = ([1, 1], 2, 3) >>> type(my_list)>>> type(my_list[0]) >>> type(my_tuple) >>> type(my_tuple[0])
Все идет нормально. Теперь попробуйте подумать о себе – что произойдет, когда мы стараемся выполнить каждую из следующих утверждений?
(1) >>>
(2) >>>
В заявлении (1), что мы пытаемся сделать, это изменить my_list
первый элемент, то есть кортеж
Отказ Так как кортеж
это неизменный Эта попытка суждена потерпеть неудачу:
>>> my_list[0][0] = 'Changed!' Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment
Обратите внимание, что то, что мы пытались сделать, это не Измените список, а скорее – измените содержимое своего первого элемента.
Давайте рассмотрим заявление (2). В этом случае мы доступны my_tuple
первый элемент, который бывает Список
и измените это. Давайте дальше рассмотрим этот случай и посмотрим на адреса этих элементов:
>>> my_tuple = ([1, 1], 2, 3) >>> id(my_tuple) 20551816 >>> type(my_tuple[0])>>> id(my_tuple[0]) 20446248
Когда мы меняемся my_tuple [0] [0]
Мы на самом деле не меняем my_tuple
вообще! Действительно, после изменения, my_tuple
Первый элемент все равно будет объектом, адрес которого в памяти 20446248
Отказ Мы делаем, однако, измените значение этого объекта:
>>> my_tuple[0][0] = 'Changed!' >>> id(my_tuple) 20551816 >>> id(my_tuple[0]) 20446248 >>> my_tuple (['Changed!', 1], 2, 3)
Так как мы модифицировали только значение my_tuple [0]
, что является смешным Список
Объект, эта операция была действительно разрешена Python.
В этом посте мы узнали о объектах Python. Мы сказали, что в Python Все это объект и должен использовать ID
и это
Чтобы углубить наше понимание того, что происходит под капотом при использовании Python для создания и модификации объектов.
Мы также узнали разницу между Meatable Объекты, которые могут быть изменены после создания, а неизменный объекты, которые не могут.
Мы видели, что когда мы просим Python изменить неизменного объекта, который связан с определенным именем, мы фактически создаем новый объект и связываете это имя для него.
Затем мы узнали, почему словарные ключи должны быть неизменный в питоне.
Понимание того, как Python «Wees» объекты – это ключ, чтобы стать лучшим программистом Python. Я надеюсь, что этот пост помог вам в вашем путешествии к освоению Python.
Омер Розенбаум , Swimm главный технический директор. Эксперт по кибер-тренажению и основатель академии безопасности контрольно-пропускных пунктов. Автор Компьютерные сети (на иврите) Отказ Посетите мой YouTube Channel Отказ