В некоторых простых приложениях, которые я написал на C/C++, я видел, как легко решать определенные задачи с помощью указателей. Сейчас, больше интересуясь другим языком: Python, я заметил отсутствие этой концепции.
Почему их нет?
Простым примером может служить то, что на языке C мы можем написать следующее:
#include <stdio.h>
int main(void) {
int a = 5;
int *b = &a;
printf("a = %d; b = %d\n", a, *b); // (1)
a = 6;
printf("a = %d; b = %d\n", a, *b); // (2)
return 0;
}
Code language: PHP (php)
(1): a = 5; b = 5 (2): a = 6; b = 6
b указывает на адрес памяти a, любое изменение a может быть обнаружено путем присвоения b. Любое косвенное присваивание *b = <значение>; будет изменять a.
Но в Python:
a = 5
b = a
print "a = {0:d}; b = {1:d}".format(a,b) # (1)
b is a # результат: True
a = 6
print "a = {0:d}; b = {1:d}".format(a,b) # (2)
b is a # результат: False
Code language: PHP (php)
(1): a = 5; b = 5 (2): a = 6; b = 5
Сначала a и b относятся к одному и тому же объекту. Затем, когда a изменяется, создается новый объект; оба объекта ссылаются на разные объекты с разными значениями.
В Python нет возможности сделать то, что в C, с этим типом данных, но можно сделать нечто подобное с изменяемыми типами данных. Однако это возможно только при внесении внутренних изменений в изменяемые данные. Например: изменение значения элемента в списке.
a = [1, 2]
b = a
print b is a # результат: True
b.append(3)
print b is a # результат: True
a = [4, 5]
print b is a # результат: False
Code language: PHP (php)
Содержание
Ответы
Ответ 1.
Их отсутствие связано с тем, что явное использование указателей является особенностью языков более низкого уровня, таких как C. Языки более высокого уровня, такие как Python, избегают их, чтобы сделать их использование более простым и гибким, а также чтобы не было необходимости знать детали модели данных.
То, что программисту Python не приходится иметь дело с указателями, не означает, что интерпретатор не использует их. На самом деле, он использует их обильно и неявно.
В Python все является объектом, созданным в динамической памяти (автоматически поддерживается). Когда вы вызываете функцию, аргументы передаются через ее указатели. Это известно как соглашение о вызове каждого объекта. Аналогично, если вы зададите a = b, a будет указателем на объект b. Таким образом, все переменные являются указателями на объекты, которые обрабатываются неявно.
Необходимо различать неизменяемые и изменяемые объекты.
Неизменяемыми являются числа, строки или кортежи. Присвоение x = 2015 создаст целочисленный объект, и x будет указывать на него, но содержимое этого объекта не может быть изменено. Если затем присвоить x = 2016, то внутренне будет создан новый объект с новым содержимым.
Другие объекты, такие как словари или списки, являются изменяемыми. В этом случае эти объекты могут быть модифицированы. Если вы имеете v = [1], а затем вызываете v.append(2), v будет по-прежнему указывать на тот же объект, но его содержимое изменится.
Короче говоря, когда вы запускаете этот код:
x = 2015
y = x
x = 2016
print x
print y
v = [1]
w = v
v.append(2)
print v
print w
Code language: PHP (php)
Результат будет:
2016
2015
[1, 2]
[1, 2]
Code language: JSON / JSON with Comments (json)
Ответ 2.
В языке C указатели обычно удовлетворяют трем потребностям: обращение к динамически резервируемым структурам, передача параметров функции по ссылке или итерация коллекции.
В случае Python и вообще объектных языков с автоматической памятью переменные выполняют функцию ссылок на динамически создаваемые структуры: можно создавать экземпляры объектов в любое время.
Объекты резервируются в динамической памяти процессов, а переменные являются ссылками на них: ссылки – это почти как абстракции указателей, с несколькими дополнительными свойствами.
По этой причине передача параметров всегда осуществляется по ссылке, поэтому указатели для этого не нужны.
Наконец, в объектных языках существуют объекты-итераторы, которые предоставляют интерфейс более высокого уровня для обхода коллекций данных.
Абстрагирование от деталей памяти процесса – это то, к чему стремятся языки, и именно поэтому указатели не нужны.