Пакет, модуль и программа

Стили написания программ

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

Высокоуровневый язык программирования предполагает платформо независимость и высокий уровень абстракции (возможность краткое описывать сложные структуры данных).

Python как процедурный язык
Декларати́вное программи́рование — это парадигма программирования, в которой задается спецификация решения задачи, то есть описывается, что представляет собой проблема и ожидаемый результат. (функциональное и логическое программирование)

Императи́вное программи́рование — это парадигма программирования (стиль написания исходного кода компьютерной программы), для которой характерно следующее:

  • в исходном коде программы записываются инструкции (команды);
  • инструкции должны выполняться последовательно;
  • данные, получаемые при выполнении предыдущих инструкций, могут читаться из памяти последующими инструкциями;
  • данные, полученные при выполнении инструкции, могут записываться в память.
Императивное программирование — это описание того, как ты делаешь что-то, а декларативное — того, что ты делаешь.

Посмотрим, какие языки являются декларативными, а какие — императивными:

  • императивные: C, C++, Java.
  • декларативные: SQL, HTML.
  • смешанные (могут быть таковыми): JavaScript, C#, Python.
Процедурное программирование - определяет программу, как последовательность команд, определяющих алгоритм решения задачи. Основная идея процедурного программирования - использование памяти для хранения данных. Основная команда - это присвоение, с помощью которой определяется и меняется память компьютера. Программа производит преобразование содержимого памяти, изменяя его от исходного состояния к результирующему.
Структура программы
Компьютерная программа - это комбинация компьютерных инструкций и данных, позволяющая аппаратному обеспечению вычислительной системы выполнять вычисления или функции управления.

Программа на языке Python может представлять из себя как простой файл с расширением .py, так и целую иерархию модулей. Рассмотрим пример:
project
    __init__.py
    os_utils.py
    main.py
    models
        __init__.py
        user.py
        group.py
    tests
        test.py
В данном примере мы видим следующую структуру: Корневой пакет project который включает модули os_utils.py и main.py, а так же пакет models и каталог tests.

В общем случае Python-проект имеет такую структуру:

  1. Проект может состоять из одного или нескольких пакетов.
  2. Пакеты содержат файлы модулей.
  3. Модули содержат инструкции.
  4. Инструкции состоят из выражений.
  5. Выражения вычисляются в объекты конкретного типа.
Пакетом в языке Python называется каталог (папка) содержащая файлы модулей и пустой файл __init__.py. Пакет несет несколько функций:

  • Группировка модулей, организация структуры проекта; Пакеты могут быть иерархически вложенными друг в друга создавая структуру проекта;
  • Создание пространства именмодулей. Пространство имен позволяет импортировать содержимое одних модулей в другие, а также использовать системные модули;
  • Инициализация модулей пакета. Когда интерпретатор Python импортирует каталог в первый раз, он автоматически запускает программный код файла __init__.py этого каталога. По этой причине обычно в эти файлы помещается программный код, выполняющий действия по инициализации, необходимые для файлов в пакете. Например, этот файл инициализации в пакете может использоваться для создания файлов с данными, открытия соединения с базой данных и так далее. Обычно файлы __init__.py не предназначены для непосредственного выполнения – они запускаются автоматически, когда выполняется первое обращение к пакету.
Названия пакетов и модулей принято именовать в нижнем регистре латинским буквами.

Модулем в Python называется обычный файл с расширением .py. Пример содержимого модуля os_utils:

# -*- coding: utf-8 -*-
import os

def show_os_info():
    os_info = os.uname()
    print('Операционная система:', os_info.sysname, os_info.release)
В коде происходит импорт модуля os из стандартной библиотеки Python, затем идет объявление процедуры show_os_info.

Для общности стоит отметить что не запрещено писать модули на других языках, например некоторые встроенные модули python написаны на Си. Модуль может содержать любой программный код на языке Python. Обратите внимание на разницу между модулем и программой - программа предназначена для того чтобы ее запускали, а пакет для того чтобы его импортировали.

Теперь рассмотрим пример программы на языке Python, наша программа будет состоять из одного файла: myos.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os

def show_os_info():
    os_info = os.uname()
    print('Операционная система:', os_info.sysname, os_info.release)

if __name__ == '__main__':
   show_os_info()
Программу можно запустить, например через консоль:
Для windows:

D:\data\projects> myos.py

Для запуска на Unix-платформах нужно добавить файлу права запускаться как программа командой chmod +x myos.py

Теперь можно запустить программу из терминала командой:

~/projects$ ./myos.py

Работа с модулями и пакетами будет рассмотрена более подробно в следующих главах.

* Сразу нужно утвердить терминологию.

В официальной документации используется термин "statement", который переводится как оператор (но в русскоязычных источниках может переводиться по разному как оператор, инструкция, конструкция или даже предложение). Давайте строго определим что мы понимаем под инструкцией:

Инструкция - это атомарная единица языка, указание интерпретатору выполнить действие. Т.е либо выполняется целиком, либо не выполняется вовсе.

Объекты и переменные
В python все объект, и эта тема будет отдельно подробно рассмотрена. Сейчас сформируем минимальное представление об объектах. Рассмотрим инструкцию присваивания: x = 5. Когда python начнет интерпретировать эту инструкцию, произойдет следующее:

  1. Создается объект в памяти, в него записывается значение 5, будет автоматически определен типа объекта как int;
  2. Создается переменная c идентификатором "x", если она не существует;
  3. В переменную a записывается ссылка на вновь созданный объект
Переменные – это записи в системной таблице, где предусмотрено место для хранения ссылок на объекты. Имя переменной должно быть уникально, и называется идентификатором переменной.

Правила именования переменных:

  1. Синтаксис идентификатора: (символ подчеркивания или алфавитный символ) + (любое число символов, цифр или символов подчеркивания);
  2. Регистрозависимость;
  3. Запрещено использовать зарезервированные слова:
4. Соглашения. Существует ряд правил, которые не являются обязательными, но которым обычно следуют на практике.
  • Имена, имеющие два символа подчеркивания в начале и в конце, являются системными именами, которые имеют особый смысл для интерпретатора. Пример: "__var__"
  • Имена, начинающиеся с одного символа подчеркивания являются скрытыми (), не импортируются инструкцией from module import *
  • Имена, начинающиеся с двух символов подчеркивания используются как имена приватных атрибутов или методов класса; Имя, состоящее из единственного символа подчеркивания, хранит результат последнего выражения при работе в интерактивной оболочке
Объекты – это области памяти с объемом, достаточным для представления значений этих объектов. Каждый объект имеет два стандартных поля:

  • описатель типа, используемый для хранения информации о типе объекта;
  • счетчик ссылок, используемый для определения момента, когда память, занимаемая объектом, может быть освобождена.
Ссылки – это автоматически разыменовываемые указатели на объекты.

Если у вас имеется опыт работы с языками, обладающими статической типизацией, такими как C, C++ или Java, вероятно, эта тема в книге вызовет у вас недоумение. Например, когда вводится инструкция x = 5, как интерпретатор Python узнает, что речь идет о целом числе? И вообще, как Python узнает, что есть что?

Как только вы начинаете задавать такие вопросы, вы попадаете в сферу действия модели динамической типизации, используемой в языке Python. Типы данных в языке Python определяются автоматически во время выполнения, а не в процессе объявлений в программном коде.
Типы данных
Python предоставляет доступ к некоторому набору встроенных типов данных, это большая тема которая будет рассмотрена отдельно, сейчас нам будет достаточно знать 4 неизменяемых встроенных типа данных: str, int float, bool, и один изменяемый встроенный тип list.

Ключевая разница изменяемых и неизменяемых это удобство использования против производительности.

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

Выражения

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