О пространстве имён и интерактивной отладке кода

avm

Опубликован:  2018-02-13T10:57:12.212158Z
500

Установка необходимых пакетов для создания полноценной среды разработки на Python3 на пакетной базе Debian stretch оказалась делом несложным и много времени не заняла. В продолжение темы попробую своими словами и в доступных образах разобрать некоторые основополагающие моменты и термины, касающиеся непосредственно разработки программ на Питоне. И начать мне хочется с пространства имён.

Каждая программа написанная на Питоне вообще, и на Python3 в частности, является исполняемым пространством имён. Пространство имён можно определить как выделенную обособленную область оперативной памяти компьютера, в которой создаются, хранятся и обрабатываются данные необходимые программе, и к которой обращается интерпретатор в процессе исполнения программы. Питон различает три вида пространств имён:

  • модуль;
  • класс;
  • функция.

Модуль - основной вид пространства имён. Каждая программа на Питоне является модулем. Модуль может быть частью пакета. Модуль может содержать определения переменных, функций, классов, а также процедурные действия над ними (изменение значений переменных, вызовы функций, создание экземпляров классов и так далее). Создать модуль можно двумя способами. Первый способ - запуск интерпретатора Питона в интерактивном режиме. Второй способ - создание текстового файла с расширением .py и исполнение этого файла интерпретатором Питона. Первый вариант стоит разобрать в деталях.

Запустить Питон в интерактивном режиме очень просто, для этого понадобится любая программа, эмулирующая терминал, я буду использовать sakura. Запускаю терминал из системного меню:

sakura

и в окне терминала вбиваю python3:

python3

В момент запуска интерпретатора в интерактивном режиме на экран выводится версия интерпретатора, версия компилятора, которым этот интерпретатор был скомпилирован, минимальная справочная информация и приглашение >>>, после которого стоит курсор в ожидании пользовательского ввода, а также в оперативной памяти компьютера создаётся пространство имён для текущей интерактивной сессии. Питон достаточно продвинут и предлагает целый набор инструментов для управления созданным пространством имён, что позволяет в свою очередь осуществлять предварительную отладку и конструирование кода непосредственно в интерактивной сессии.

Список уже существующих объектов в текущем пространстве имён можно посмотреть так:

>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> 

Как видно из предыдущего листинга, вновь созданное пространство имён уже содержит несколько предопределённых объектов. Стоит отметить, что, поскольку Питон - объектно-ориентированный диалект, всё в Питоне есть object, object - это самый базовый тип, от которого наследуют все остальные встроенные типы этого диалекта. Среди предопределённых объектов в созданном пространстве имён чуть подробней стоит остановиться на __builtins__, __name__ и __package__. Посмотрим, какую информацию можно получить об этих объектах. Сначала проверю, являются ли они экземплярами object:

>>> isinstance(__builtins__, object)
True
>>> isinstance(__name__, object)
True
>>> isinstance(__package__, object)
True
>>> 

Теперь посмотрю тип каждого из этих объектов:

>>> type(__builtins__)
<class 'module'>
>>> type(__name__)
<class 'str'>
>>> type(__package__)
<class 'NoneType'>
>>> 

Ну и наконец посмотрю, что возвращает каждый из этих объектов:

>>> print(__builtins__)
<module 'builtins' (built-in)>
>>> print(__name__)
__main__
>>> print(__package__)
None
>>> 

Таким образом, я совершенно резонно делаю вывод, что каждый объект в пространстве имён имеет три составляющие:

  • имя;
  • тип;
  • возвращаемое значение.

Попробую создать новый объект в пространстве имён своей интерактивной сессии, назначаю этому объекту имя x и присваиваю ему в качестве значения целое число:

>>> x = 1

В результате в текущем пространстве имён появился новый объект, у которое есть имя, тип и возвращаемое значение, и к этому объекту можно обратиться по его имени:

>>> type(x)
<class 'int'>
>>> print(x)
1
>>> 

Попробую изменить значение переменной x:

>>> x = 'hello world!'

Теперь имени x соответствует новый объект:

>>> type(x)
<class 'str'>
>>> print(x)
hello world!
>>> 

Следует обратить внимание, что тип объекта в Питоне определяется динамически в зависимости от типа хранящихся в этом объекте данных. Это свойство Питона принято называть динамической типизацией.

По имени к объекту можно обращаться и выполнять с этим объектом процедурные действия, а все объекты без имени становятся добычей сборщика мусора и автоматически удаляются из пространства имён. Например, когда я присвоил уже существующей переменной x новое значение, я создал новый объект, а предыдущий объект (целое число 1), на который ссылалась переменная x, утратил имя и был автоматически удалён из пространства имён сборщиком мусора.

Получить объект в пространстве имён можно и другими способами, а именно:

  • можно импортировать объект из другого модуля;
  • можно определить класс;
  • можно определить функцию.

В настоящий момент пространство имён моей интерактивной сессии содержит кроме предопределённых объектов ещё и пользовательскую переменную x:

>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']
>>> 

Каждая пользовательская переменная имеет соответствующие её типу методы, список этих методов для конкретного объекта тоже можно увидеть:

>>> dir(x)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> 

По каждому методу можно получить справку не покидая интерактивной сессии:

>>> help(x.endswith)

Help on built-in function endswith:

endswith(...) method of builtins.str instance
    S.endswith(suffix[, start[, end]]) -> bool

    Return True if S ends with the specified suffix, False otherwise.
    With optional start, test S beginning at that position.
    With optional end, stop comparing S at that position.
    suffix can also be a tuple of strings to try.
(END)

Примечание: чтобы убрать с экрана справку и вернуться в интерактивную сессию, достаточно нажать клавишу q.

Поскольку объект в пространстве имён можно создать, объект из пространства имён можно и удалить. Делается это так:

>>> del x
>>> 

Теперь в пространстве имён текущей интерактивной сессии нет объекта с именем x:

>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> 

Возникает резонный вопрос, а как в текущем пространстве имён появились имена dir, type, isinstance, help, print? Все перечисленные имена являются встроенными функциями Питона. Все они подгружаются в пространство имён интерактивной сессии автоматически при запуске интерпретатора из модуля builtins, который содержит встроенные функции и классы. Список имён в модуле builtins тоже можно увидеть с помощью dir:

>>> dir(__builtins__)

И если явным образом импортировать этот модуль, то можно увидеть следующую картину:

>>> import builtins
>>> __builtins__ is builtins
True
>>> 

Повторюсь, модуль builtins подгружается автоматически в каждый модуль Питона и не требует явного импорта.

По каждому объекту из модуля builtins можно получить справку при помощи встроенной функции help не покидая интерактивную сессию, например:

>>> help(isinstance)

Подробнее на модуле builtins и его составляющих я остановлюсь отдельно в ближайшей перспективе. Примеры использования некоторых встроенных функций и интерактивную отладку кода можно посмотреть в Python3, решаем простые задачи с помощью встроенных функций. Кроме того, процесс создания элементарной программы на Питоне с использованием интерактивной отладки описан в Пишем на Питоне игру в кости. Замечу, что иногда интерактивная отладка бывает увлекательнее самого захватывающего экшена и позволяет найти решение достаточно сложных и запутанных задач.

 
Комментарии: