Переменная
Императивные языки программирование основываются на виртуальных машинах с архитектурой фон Неймана. Главными компонентами такой архитектуры являются память, в ячейках которой хранятся данные и команды, и процессор, меняющий содержимое памяти.
Переменная является абстракцией над ячейками памяти в архитектуре фон Неймана.
Переменная чаще всего обладает именем, задаёт тип данных и область памяти, в которой хранится значение переменной. Также переменной характерно время жизни, в течении которого в указанной области памяти хранится валидное значение.
Попытаемся относиться к переменной как к кортежу из перечисленных аттрибутов <имя, тип, адрес, время жизни>. Попробуем поиграть этими атрибутами.
Имя и область видимости
Имя переменной - текстовый идентификатор, уникальный в области видимости переменной.
Семантическое значение имени переменной сложно переоценить. Короткое название, обычно не длиннее двух-трех слов на английском языке, позволяет программисту передать смысл, назначение переменной.
О хорошем именовании переменных
Хорошо названная переменная, по мнению многих программистов, может не требовать комментария.
Сравните 2 участка кода. В первом я переименовал переменные в ничего не значащие акронимы. Несмотря на полные названия функции и метода, код нечитаемый.
def get_template(n, u=None):
ee = _engine_list(n)
for e in ee:
return e.get_template(n)
Во втором кода участке я сохранил названия автора. Код легко прочитать и понять.
def get_template(template_name, using=None):
engines = _engine_list(using)
for engine in engines:
return engine.get_template(template_name)
На первый взгляд может показаться, что правильное именование влияет лишь на читаемость программы и вредит скорости создания, однако это верно лишь для одноразовых программ. Через неделю даже автор не сможет разобраться, что он имел в виду под именами e, z, h.
Область видимости переменной
Область видимости неразрывно свзязана с именем переменной, поэтому мы не вынесли область видимости в отдельный атрибут переменной.
Область видимости переменной задаётся контекстом определения. Глобальная статическая переменная может быть определена в пространстве имён (namespace) или в пакете (package). Переменная-аттрибут класса размещается в области видимости класса (class). Область видимости локальной переменной функции ограничена участком кода данной функции. Даже блок кода может ограничивать область видимости переменной.
Имя переменной обязано быть уникальным в текущем пространстве имён, контексте объявления переменной. Это правило не только облегчает лексический анализ программы, но и обеспечивает устойчивость программы к изменениям. Предположим, компилятор может различить две переменные, обладающих одинаковым именем, но разными типами, задающими разный интерфейс:
std::string message;
windowlib::Dialog message;
// собираем сообщение
message = "Hello, ";
message.append( "naming conflict!" );
// выводим диалог на экран
message.show( message.c_ptr() );
Но что случится, если интерфейс одного из классов будет изменен с конфликтом в данном участке кода. Такое может случиться если в классе windowlib::Window, базовом классе windowlib::Dialog, будет добавлен метод append( const char* template )? Приведенный участок кода перестанет компилироваться из-за конфликта имён и интерфейсов. Такое решение оказывается очень хрупким. Пожтому от языков программирования не требуется различать переменные с одинаковым именем.
Чаще всего нет ограничения на имена переменных, размещенных в разных пространствах имён. Языки задают правила, по которым разрешенаются неоднозначности. Самое простое правило разрешения неоднозначности вглядит так: переменная в локальном контексте имеет приоритет над переменной в охватывающем контексте. Однако даже такое простое правило может приводить к досадным ошибкам. Так происходит в языках с неявным определением переменной:
state = 0
def first_phase():
state = 1
# выполняем первую фазу обработки
В данном коде в функции first_phase() глобальная переменная state не была изменена. Вместо этого была определена локальная переменная со значением 1.
Для исправления этой ситуации в язык приходится вводить новые ключевые слова:
state = 0
def first_phase():
global state
state = 1 # теперь это не локальная переменная
# выполняем первую фазу обработки
Альтернативные имена
Теперь попробуем немного поиграть с именем, как атрибутом переменной. Может ли быть у переменной несеколько имён? Может, и это оказывается полезным свойством языка. Альтернативные имена или алиасы
Тип переменной
Время жизни
Время жизни и область видимости
del в Python удаляет имя переменной, но не значение, на которое ссылается переменная. Имя становится недоступным - выходит из области видимости. Значение же не будет разрушено, если на него есть другие ссылки.
Адрес переменной
Уникальность объекта
is a и operator ==
Копирование объектов
Копирование неизменяемых (immutable) объектов не имеет смысла.