01.10.2017

Основы Python

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

Материал рассчитан на людей, не знакомых с языками программирования.

Для начала Python надо установить. Затем нужно поставить удобную среду для написания программ на Python. Этим двум шагам посвящена отдельная статья на портале.

Если все установлено и настроено, можно начинать.

Поехали!

Переменные

Переменная — ключевое понятие в любом языке программирования (и не только в них). Проще всего представить переменную в виде коробки с ярлыком. В этой коробке хранится что-то (число, матрица, объект, …) представляющее для нас ценность.

Например, мы хотим создать переменную x, которая должна хранить значение 10. В Python код создания этой переменной будет выглядеть так:

x = 10

Слева мы объявляем переменную с именем x. Это равносильно тому, что мы приклеили на коробку именной ярлык. Далее идет знак равенства и число 10. Знак равенства здесь играет необычную роль. Он не означает, что «x равно 10». Равенство в данном случае кладет число 10 в коробку. Если говорить более корректно, то мы присваиваем переменной x число 10.

Теперь, в коде ниже мы можем обращаться к этой переменной, также выполнять с ней различные действия.

Можно просто вывести значение этой переменной на экран:

x=10
print(x)

Надпись print(x) представляет собой вызов функции. Их мы будем рассматривать далее. Сейчас важно то, что эта функция выводит в консоль то, что расположено между скобками. Между скобками у нас стоит x. Ранее мы присвоили x значение 10. Именно 10 и выводится в консоли, если вы выполните программу выше.

С переменными, которые хранят числа, можно выполнять различные простейшие действия: складывать, вычитать, умножать, делить и возводить в степень.

x = 2
y = 3

# Сложение
z = x + y
print(z) # 5

# Разность
z = x - y
print(z) # -1

# Произведение
z = x * y
print(z) # 6

# Деление
z = x / y
print(z) # 0.66666...

# Возведение в степень
z = x ** y
print(z) # 8

В коде выше мы вначале создаем две переменные, содержащие 2 и 3. Затем создаем переменную z, которая хранит результат операции с x и y и выводит результаты в консоль. На этом примере хорошо видно, что переменная может менять свое значение в ходе выполнения программы. Так, наша переменная z меняет свое значение аж 5 раз.

Функции

Иногда возникает необходимость много раз выполнять одни и те же действия. Например, в нашем проекте нужно часто выводить 5 строчек текста.

«Это очень важный текст!»
«Этот текст нильзя ни прочитать»
«Ошибка в верхней строчке допущена специально»
«Привет и пока»
«Конец»

Наш код будет выглядеть так:

x = 10

y = x + 8 - 2

print("Это очень важный текст!")
print("Этот текст нильзя не прочитать")
print("Ошибка в верхней строчке допущена специально")
print("Привет и пока")
print("Конец")

z = x + y

print("Это очень важный текст!")
print("Этот текст нильзя не прочитать")
print("Ошибка в верхней строчке допущена специально")
print("Привет и пока")
print("Конец")

test = z

print("Это очень важный текст!")
print("Этот текст нильзя не прочитать")
print("Ошибка в верхней строчке допущена специально")
print("Привет и пока")
print("Конец")

Выглядит все это очень избыточно и неудобно. Кроме того, во второй строчке допущена ошибка. Ее можно исправить, но исправлять придется сразу в трех местах. А если у нас в проекте эти пять строчек вызываются 1000 раз? И все в разных местах и файлах?

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

Функция — отдельный блок кода, который можно вызывать по имени.

Задается функция с помощью ключевого слова def . Далее следует название функции, затем скобки и двоеточие. Дальше с отступом надо перечислить действия, которые будут выполнены при вызове функции.

def print_5_lines():
    print("Это очень важный текст!")
    print("Этот текст нильзя не прочитать")
    print("Ошибка в верхней строчке допущена специально")
    print("Привет и пока")
    print("Конец")

Теперь мы определили функцию print_5_lines(). Теперь, если в нашем проекте нам в очередной раз надо вставить пять строчек, то мы просто вызываем нашу функцию. Она автоматически выполнит все действия.

# Определяем функцию
def print_5_lines():
    print("Это очень важный текст!")
    print("Этот текст нильзя не прочитать")
    print("Ошибка в верхней строчке допущена специально")
    print("Привет и пока")
    print("Конец")

# Код нашего проекта
x = 10

y = x + 8 - 2

print_5_lines()

z = x + y

print_5_lines()

test = z

print_5_lines()

Удобно, не правда ли? Мы серьезно повысили читаемость кода. Кроме того, функции хороши еще и тем, что если вы хотите изменить какое-то из действий, то достаточно подправить саму функцию. Это изменение будет работать во всех местах, где вызывается ваша функция. То есть мы можем исправить ошибку во второй строчке выводимого текста («нильзя» > «нельзя») в теле функции. Правильный вариант автоматически будет вызываться во всех местах нашего проекта.

Функции с параметрами

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

Переменные, которые мы передаем в функцию, называются аргументами.

Напишем простую функцию, которая складывает два данных ей числа и возвращает результат.

def sum(a, b):
    result = a + b
    return result

Первая строчка выглядит почти так же, как и обычные функции. Но между скобок теперь находятся две переменные. Это параметры функции. Наша функция имеет два параметра (то есть принимает две переменные).

Параметры можно использовать внутри функции как обычные переменные. На второй строчке мы создаем переменную result, которая равна сумме параметров a и b. На третьей строчке мы возвращаем значение переменной  result.

Теперь, в дальнейшем коде мы можем писать что-то вроде:

new = sum(2, 3)
print(new)

Мы вызываем функцию sum и по очереди передаем ей два аргумента: 2 и 3. 2 становится значением переменной a, а 3 становится значением переменной b. Наша функция возвращает значение (сумму 2 и 3), и мы используем его для создания новой переменной new.

Запомните. В коде выше числа 2 и 3 — аргументы функции sum. А в самой функции  sum переменные a и b — параметры. Другими словами, переменные, которые мы передаем функции при ее вызове называются аргументами. А вот внутри функции эти переданные переменные называются параметрами. По сути, это два названия одного и того же, но путать их не стоит.

Рассмотрим еще один пример. Создадим функцию square(a), которая принимает какое-то одно число и возводит его в квадрат:

def square(a):
    return a * a

Наша функция состоит всего из одной строчки. Она сразу возвращает результат умножения параметра a на a.

Я думаю вы уже догадались, что вывод данных в консоль мы тоже производим с помощью функции. Эта функция называется print() и она выводит в консоль переданный ей аргумент: число, строку, переменную.

Массивы

Если переменную можно представлять как коробку, которая что-то хранит (не обязательно число), то массивы можно представить в виде книжных полок. Они содержат сразу несколько переменных. Вот пример массива из трех чисел и одной строки:

array = [1, 89, 3, "строка"]

Вот и пример, когда переменная содержит не число, на какой-то другой объект. В данном случае, наша переменная содержит массив. Каждый элемент массива пронумерован. Попробуем вывести какой-нибудь элемент массива:

array = [1, 89, 3, "строка"]

print( array[1] )

В консоли вы увидите число 89. Но почему 89, а не 1? Все дело в том, что в Python, как и во многих других языках программирования, нумерация массивов начинается с 0. Поэтому array[1] дает нам второй элемент массива, а не первый. Для вызова первого надо было написать array[0].

Размер массива

Иногда бывает очень полезно получить количество элементов в массиве. Для этого можно использовать функцию len(). Она сама подсчитает количество элементов и вернет их число.

array = [1, 89, 3, "строка"]

print( len(array) )

В консоли выведется число 4.

Условия и циклы

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

Кроме того, часто возникает необходимость много раз повторить практически одинаковую последовательность команд.

В первой ситуации помогают условия, а во второй — циклы.

Условия

Условия нужны для того, чтобы выполнить два разных набора действий в зависимости от того, истинно или ложно проверяемое утверждение.

В Python условия можно записывать с помощью конструкции if: ... else: .... Пусть у нас есть некоторая переменная x = 10. Если x меньше 10, то мы хотим разделить x на 2. Если же x больше или равно 10, то мы хотим создать другую переменную new, которая равна сумме x и числа 100. Вот так будет выглядеть код:

x = 10

if(x < 10):
    x = x / 2
    print(x)
else:
    new = x + 100
    print(new)

После создания переменной x мы начинаем записывать наше условие.

Начинается все с ключевого слова if (в переводе с английского «если»). В скобках мы указываем проверяемое выражение. В данном случае мы проверяем, действительно ли наша переменная x меньше 10. Если она действительно меньше 10, то мы делим ее на 2 и выводит результат в консоль.

Затем идет ключевое слово else, после которого начинается блок действий, которые будут выполнены, если выражение в скобках после if ложное.

Если она больше или равна 10, то мы создаем новую переменную new, которая равна x + 100 и тоже выводим ее в консоль.

Циклы

Циклы нужны для многократного повторения действий. Предположим, мы хотим вывести таблицу квадратов первых 10 натуральных чисел. Это можно сделать так.

print("Квадрат 1 равен " + str(1**2))
print("Квадрат 2 равен " + str(2**2))
print("Квадрат 3 равен " + str(3**2))
print("Квадрат 4 равен " + str(4**2))
print("Квадрат 5 равен " + str(5**2))
print("Квадрат 6 равен " + str(6**2))
print("Квадрат 7 равен " + str(7**2))
print("Квадрат 8 равен " + str(8**2))
print("Квадрат 9 равен " + str(9**2))
print("Квадрат 10 равен " + str(10**2))

Пусть вас не удивляет тот факт, что мы складываем строки. «начало строки» + «конец» в Python означает просто соединение строк: «начало строкиконец». Так же и выше мы складываем строку «Квадрат x равен » и преобразованный с помощью функции str(x**2) результат возведения числа во 2 степень.

Выглядит код выше очень избыточно. А что, если нам надо вывести квадраты первых 100 чисел? Замучаемся выводить…

Именно для таких случаев и существуют циклы. Всего в Python 2 вида циклов:  while и for. Разберемся с ними по очереди.

Цикл while повторяет необходимые команды до тех пор, пока остается истинным условие.

x = 1
while x <= 100:
    print("Квадрат числа " + str(x) + " равен " + str(x**2))
    x = x + 1

Сначала мы создаем переменную и присваиваем ей число 1. Затем создаем цикл while и проверяем, меньше (или равен) ли 100 наш x. Если меньше (или равен) то мы выполняем два действия:

  1. Выводим квадрат x
  2. Увеличиваем x на 1

После второй команды программа возвращается к условию. Если условие снова истинно, то мы снова выполняем эти два действия. И так до тех пор, пока x не станет равным 101. Тогда условие вернет ложь и цикл больше не будет выполняться.

Цикл for предназначен для того, чтобы перебирать массивы. Запишем тот же пример с квадратами первой сотни натуральных чисел, но уже через цикл for.

for x in range(1,101):
    print("Квадрат числа " + str(x) + " равен " + str(x**2))

Разберем первую строку. Мы используем ключевое слово for для создания цикла. Далее мы указываем, что хотим повторить определенные действия для всех x в диапазоне от 1 до 100. Функция range(1,101) создает массив из 100 чисел, начиная с 1 и заканчивая 100.

Вот еще пример перебора массива с помощью цикла for:

for i in [1, 10, 100, 1000]:
    print(i * 2)

Код выше выводит 4 цифры: 2, 20, 200 и 2000. Тут наглядно видно, как берет каждый элемент массива и выполняет набор действий. Затем берет следующий элемент и повторяет тот же набор действий. И так пока элементы в массиве не кончатся.

Классы и объекты

В реальной жизни мы оперируем не переменными или функциями, а объектами. Ручка, машина, человек, кошка, собака, самолет — объекты. Теперь начнем подробно рассматривать кошку.

Она обладает некоторыми параметрами. К ним относятся цвет шерсти, цвет глаз, ее кличка. Но это еще не все. Помимо параметров, кошка может выполнять различные действия: мурлыкать, шипеть и царапаться.

Только что мы схематически описали всех кошек в целом. Подобное описание свойств и действий какого-то объекта (например, кошки) на языке Python и называется классом. Класс — просто набор переменных и функций, которые описывают какой-то объект.

Важно понимать разницу между классом и объектом. Класс — схема, которая описывает объект. Объект — ее материальное воплощение. Класс кошки — описание ее свойств и действий. Объект кошки и есть сама реальная кошка. Может быть много разных реальных кошек — много объектов-кошек. Но класс кошки только один. Хорошей демонстрацией служит картинка ниже:

 

Классы

Для создания класса (схемы нашей кошки) надо написать ключевое слово class и затем указать имя этого класса:

class Cat:

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

Метод — функция, определенная внутри класса.

Словесно мы уже описали методы кошки выше: мурлыкать, шипеть, царапаться. Теперь сделаем это на языке Python.

# Класс кошки
class Cat:

 # Мурлыкать
 def purr(self):
 print("Муррр!")

 # Шипеть
 def hiss(self):
 print("Кшшш!")

 # Царапаться
 def scrabble(self):
 print("Царап-царап!")

Вот так все просто! Мы взяли и определили три обычные функции, но только внутри класса.

Для того, чтобы разобраться с непонятным параметром self, добавим еще один метод нашей кошке. Этот метод будет разом вызывать все три уже созданных метода.

# Класс кошки
class Cat:

    # Мурлыкать
    def purr(self):
        print("Муррр!")

    # Шипеть
    def hiss(self):
        print("Кшшш!")

    # Царапаться
    def scrabble(self):
        print("Царап-царап!")
        
    # Все вместе
    def all_in_one(self):
        self.purr()
        self.hiss()
        self.scrabble()

Как видите, обязательный для любого метода параметр self позволяет нам обращаться к методами и переменным самого класса! Без этого аргумента выполнить подобные действия мы бы не смогли.

Давайте теперь зададим свойства нашей кошки (цвет шерсти, цвет глаз, кличка). Как это сделать? В абсолютно любом классе можно определить функцию __init__(). Эта функция всегда вызывается, когда мы создаем реальный объект нашего класса.

# Класс кошки
class Cat:

    # Действия, которые надо выполнять при создании объекта "Кошка"
    def __init__(self, wool_color, eyes_color, name):
        self.wool_color = wool_color
        self.eyes_color = eyes_color
        self.name = name

    # Мурлыкать
    def purr(self):
        print("Муррр!")

    # Шипеть
    def hiss(self):
        print("Кшшш!")

    # Царапаться
    def scrabble(self):
        print("Царап-царап!")

    # Все вместе
    def all_in_one(self):
       self.purr()
       self.hiss()
       self.scrabble()

В выделенном выше методе __init__() мы задаем переменные нашей кошки. Как мы это делаем? Сначала мы передаем в этот метод 3 аргумента, отвечающие за цвет шерсти, цвет глаз и кличку. Затем, мы используем параметр self для того, чтобы при создании объекта сразу задать нашей кошки 3 описанных выше атрибута.

Что означает эта строчка?

self.wool_color = wool_color

В левой части мы создаем атрибут для нашей кошки с именем wool_color, а дальше мы присваиваем этому атрибуту значение, которое содержится в параметре wool_color, который мы передали в функцию __init__(). Как видите, строчка выше не отличается от обычного создания переменной. Только приставка self указывает на то, что эта переменная относится к классу Cat.

Атрибут — переменная, которая относится к какому-то классу.

Итак, мы создали готовый класс кошки. Вот его код:

# Класс кошки
class Cat:

    # Действия, которые надо выполнять при создании объекта "Кошка"
    def __init__(self, wool_color, eyes_color, name):
        self.wool_color = wool_color
        self.eyes_color = eyes_color
        self.name = name

    # Мурлыкать
    def purr(self):
        print("Муррр!")

    # Шипеть
    def hiss(self):
        print("Кшшш!")

    # Царапаться
    def scrabble(self):
        print("Царап-царап!")

    # Все вместе
    def all_in_one(self):
        self.purr()
        self.hiss()
        self.scrabble()

Объекты

Мы создали схему кошки. Теперь давайте создадим по этой схеме реальный объект кошки:

my_cat = Cat("черный", "зеленые", "Зося")

В строке выше мы создаем переменную my_cat, а затем присваиваем ей объект класса Cat. Выглядит все этот как вызов некоторой функции Cat(...). На самом деле так и есть. Этой записью мы вызываем метод __init__() класса Cat. Функция __init__() в нашем классе принимает 4 аргумента: сам объект класса self, который указывать не надо, а также еще 3 разных аргумента, которые затем становятся атрибутами нашей кошки.

Итак, с помощью строчки выше мы создали реальный объект кошки. Наша кошка имеет следующие атрибуты: черную шерсть, зеленые глаза и кличку Зося. Давайте выведем эти атрибуты в консоль:

print(my_cat.wool_color)
print(my_cat.eyes_color)
print(my_cat.name)

То есть обратиться к атрибутам объекта мы можем, записав имя объекта, поставив точку и указав имя желаемого атрибута.

Атрибуты кошки можно менять. Например, давайте сменим кличку нашей кошки:

my_cat.name = "Нюша"

Теперь, если вы вновь выведете в консоль имя кошки, то вместо Зоси увидите Нюшу.

Напомню, что класс нашей кошки позволяет ей выполнять некоторые действия. Если мы погладим нашу Зосю/Нюшу, то она начнет мурлыкать:

my_cat.purr()

Выполнение данной команды выведет в консоль текст «Муррр!». Как видите, обращаться к методам объекта так же просто, как и обращаться к его атрибутам.

Модули

Любой файл с расширением .py является модулем. Даже тот, в котором вы отрабатываете эту статью. Зачем они нужны? Для удобства. Очень много людей создают файлы с полезными функциями и классами. Другие программисты подключают эти сторонние модули и могут использовать все определенные в них функции и классы, тем самым упрощая себе работу.

Например, вам не нужно тратить время и писать свои функции для работы с матрицами. Достаточно подключить модуль numpy и использовать его функции и классы.

На данный момент другие Python программисты написали уже свыше 110 000 разнообразных модулей. Упоминавшийся выше модуль numpy позволяет быстро и удобно работать с матрицами и многомерными массивами. Модуль math предоставляет множество методов для работы с числами: синусы, косинусы, переводы градусов в радианы и прочее и прочее…

Установка модуля

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

Если вы хотите использовать модуль, который не входит в стандартный набор, то вам потребуется установить его. Для установки модуля откройте командую строку (Win + R, затем введите в появившемся поле «cmd») и введите в нее команду:

pip install [название_модуля]

Начнется процесс установки модуля. Когда он завершится, вы можете спокойно использовать установленный модуль в своей программе.

Подключение и использование модуля

Сторонний модуль подключается очень просто. Надо написать всего одну короткую строку кода:

import [название_модуля]

Например, для импорта модуля, позволяющего работать с математическими функциями, надо написать следующее:

import math

Как обратиться к функции модуля? Надо написать название модуля, затем поставить точку и написать название функции/класса. Например, факториал 10 находится так:

math.factorial(10)

То есть мы обратились к функции factorial(a), которая определена внутри модуля  math. Это удобно, ведь нам не нужно тратить время и вручную создавать функцию, которая считает факториал числа. Можно подключить модуль и сразу выполнить необходимое действие.

Аватара автора Петр Радько

Петр Радько

Сфера интересов — нейросети как стык передовых исследований по математике, биологии, информатике и физике. Мне нравится делиться тем, что я узнал. Считаю, что любую концепцию можно изложить просто и наглядно. Нейронные сети на глазах меняют наш мир. И надо знать их и уметь ими пользоваться!

Комментарии

avatar
Alexander Adamenko
Alexander Adamenko

Очень круто написано, большое спасибо!

Сергей
Сергей

Идеально. Лучшее из того, что я видел.

Я опытный программист. Пишу на PHP и JS (хоть серверный, хоть клиентский). Нейросети привлекают меня как хобби. А для занятия любимым хобби необходимо базовое понимание пайтона. У вас прям идеальная статься для тех, кто уже умеет программировать. Сама так сказать выжимка базовых действий и принципов. Для всего остального есть мануалы. Большое спасибо за легкое введение.

Шикарная вещь!
Лучшее объяснение по питону, которое я видел.
Так держать

Dimon
Dimon

Петр, спасибо за то что ты создаёшь данный портал.

Вставить формулу как
Блок
Строка
Дополнительные настройки
Цвет формулы
Цвет текста
#333333
Используйте LaTeX для набора формулы
Предпросмотр
\({}\)
Формула не набрана
Вставить

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: