Итоги первой недели
Основы языка Python
Python — современный мультипарадигменный язык программирования высокого уровня. Разработан в 1991 году, автор — голландец Гвидо Ван Россум (Guido van Rossum). Python ориентирован на повышение производительности труда программиста и хорошую читаемость кода.
Арифметика
Документация: https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
Синтаксис записи выражений обычный (скобки, операции, все дела).
Типы: целые — int
, вещественные — float
, комплексный — complex
.
Примеры числовых констант:
- целочисленные (int):
1
,5
,199999
,0b100101
(двоичные числа),0o755
(восьмиричные числа),0x1eff000000
или0x1EFF000000
(шестнадцатиричные числа) - вещественные (float):
1.0
,0.02
,3.1415926
,1.14e2
(то есть 1,14⋅10²) - комплексные (complex):
3 + 2j
или3 + 2J
(символj
илиJ
— обозначение мнимой части числа)
Операторы
x + 2
— сложениеx - 2
— вычитаниеx * 2
— умножениеx // 2
— деление (целочисленное, два слэша подряд)x / 2
— деление (настоящее)x ** 2
— возведение в степень (две звёздочки подряд)x % 2
— остаток от деленияx | 2
— побитовое ИЛИx & 2
— побитовое Иx ^ 2
— исключающее ИЛИ (xor)~x
— побитовое НЕx << 2
,x >> 2
— побитовый сдвиг влево и вправо- Модифицирующие операторы:
x += 2
x -= 2
x *= 2
x /= 2
x %= 2
и т. д. — как в С-подобных языках, например,x += 2
— это то же самое, чтоx = x + 2
.
Логические операторы
https://docs.python.org/3/library/stdtypes.html#boolean-operations-and-or-not
https://docs.python.org/3/library/stdtypes.html#comparisons
Тип для логических выражений — bool
.
Константы: True
, False
(обязательно с большой буквы).
x > 2
x < 2
x == 2
x != 2
x >= 2
x <= 2
— как обычно2 < x <= 4
— двойное сравнение (эквивалентно2 < x and x <= 4
). В каком ещё языке вы такое видели?- Логические связки:
a or b
— или
a and b
— и
not a
— не
Строки
https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str
https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
Тип — str
.
Способы создания строки:
"Hello"
— в двойных кавычках'Hello'
— в одинарных кавычках- Длинные многострочные строки берутся в тройной разделитель:
s = """This string is
sooo long
and useless
"""
Можно вместо трёх двойных кавычек применять три одинарных (три апострофа).
Две строковых константы, между которыми нет ничего, кроме пробелов, соединяются в одну:
'Foo' 'bar'
→'Foobar'
Операции над строками:
- Строки можно соединять оператором +:
'Foo' + 'bar'
→'Foobar'
- Повторение строк через оператор *:
'Foo' * 3
→'FooFooFoo'
str(x)
— строковое представление объекта x (не для любого объекта)int(s)
,float(s)
— преобразование строки в число. Если вs
не число, выбрасывет исключениеValueError
.repr(x)
— внутреннее представление объектаx
в виде строки (для отладки)
Форматные строки
https://docs.python.org/3/library/string.html#formatstrings
У строк есть метод format
, позволяющий подставлять в строку значения.
'I have {} apples'.format(3 + 2)
→ 'I have 5 apples'
'I have {num} apples'.format(num = 3 + 2)
→ 'I have 5 apples'
Срезы строк
s = 'Python'
len(s)
— длина строкиs[0]
== 'P's[1]
== 'y's[-1]
== 'n' (последний символ)s[-2]
== 'o' (предпоследний)s[0:2]
== 'Py' — символы с 0 по 2 (исключая 2)s[2:]
== 'thon' — символы со 2 и до концаs[:3]
== 'Pyt' — символы с начала и до 3 (исключая 3)s[0:5:2]
== 'Pto' — символы с 0 по 5 с шагом 2 (то есть каждый второй)
Проверка на наличие символов в строке (или элемента в последовательности)
x in s
—True
, если подстрока x есть в строке sx not in s
— аналогичноnot (x in s)
s.count(x)
— количество вхождений подстроки x в строку s
Списки
https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
https://docs.python.org/3/library/stdtypes.html#lists
Список — модифицируемая последовательность (в отличии от строк).
Название типа — list
.
Создание списка
[]
— пустой список[1, 2, 5, 'Low', 'High']
— список из 5 элементов[0] * 5
— список из пяти нулей ([0, 0, 0, 0, 0]
)list('zorg')
— преобразование любой последовательности в список (в данном случае результат['z', 'o', 'r', 'g']
)
Со списками можно делать то же, что и со строками (и любыми последовательностями), но их можно модифицировать, поэтому доступно следующее:
Модификация среза
m = [0, 1, 2, 3, 4, 5]
m[0] = 1
→[1, 1, 2, 3, 4, 5]
m[-1] = 10
→[1, 1, 2, 3, 4, 10]
m[1:3] = ['a', 'b', 'c', 'd']
→[1, 'a', 'b', 'c', 'd', 3, 4, 10]
— обратите внимание, что список, вставленный вместо среза, был длиннее. Срез удаляется и заменяется новыми значениями. Да, даже срез с шагом можно использовать, однако в этом случае число элементов в срезе и в замене должно совпадать.del m[0]
→['a', 'b', 'c', 'd', 3, 4, 10]
— удаление элемента.del m[1::2]
→['a', 'c', 3, 10]
— удалили каждый второй элемент, начиная со второго (индекс у него 1) и до конца списка (вторая граница пропущена). Удалить можно любой срез.- и так далее, любые комбинации
Методы списка
m.append(x)
— добавить значение x в конец списка как новый элемент.m.extend(q)
— добавить список (или иную последовательность) q к концу списка m. То же самое, чтоm += q
.m.clear()
— очистка всего списка, то же, чтоdel m[:]
.m.copy()
— создание нового списка и копирование значений из m в него, новый список — результат этой функции:z = m.copy()
.m.insert(i, x)
— вставка элемента x в список m на позицию i (элементы списка с i-того сдвигаются вправо).m.remove(x)
— удаление первого слева элемента списка m, равного x. Чтобы удалить все такие элементы, надо вызватьremove
несколько раз (столько, сколько таких элементов).m.pop()
— удаляет последнего элемента списка и возвращает его значение.m.reverse()
— переворачивает список ([1, 2, 3].reverse()
→[3, 2, 1
).m.sort()
— сортирует список по возрастанию.- И так далее, смотрите документацию.
Кортежи
https://docs.python.org/3/library/stdtypes.html#tuples
Кортеж — немодифицируемая последовательность. Обычно применяется для гетерогенных данных. Используется вместо пар, троек, векторов. Так же полезны, если из функции нужно вернуть не одно, а одновременно несколько значений (например, функция поиска возвращает и номер найденного объекта, и сам объект)
Название типа — tuple
.
Создание кортежа
()
— пустой кортеж.(1,)
— кортеж из одного элемента.(1, 2, 3)
— кортеж их трёх элементов.tuple('Hello')
— преобразование типа (результат — кортеж('H', 'e', 'l', 'l', 'o')
).- Вообще, круглые скобки обязательны для пустого кортежа. Любые
значения, перечисленные через запятую, образуют кортеж, если только
они не в квадратных или фигурных скобках и не являются параметрами
функции. То есть
k = 1, 2, 3
— это уже кортеж из трёх чисел. Но:
k = some_function(1, 2, 3)
— это вызов функции с передачей ей трёх аргументов, здесь нет кортежа. Чтобы передать в функцию кортеж, его надо взять в круглые скобки:
k = some_function((1, 2, 3))
Над кортежами можно производить те же операции, что над строками.
Несколько полезных функций
zip(s, p, q...)
— упаковка нескольких последовательностей. Возвращает итерируемый объект, который возвращает кортежи вида(s[i], p[i], q[i],...)
. Аргументов может быть 1 или больше. Этот объект можно использовать в циклеfor
, или создать из него последовательность. Пример:
x = list(zip([1, 2, 3], ['a', 'b', 'c']))
x == [(1, 'a'), (2, 'b'), (3 , 'c')]
range(x, y, s)
— возвращает итерируемый объект, который возвращает числа от x до y с шагом s. Если шаг не указан, он считается равным 1. Если не указано значение y, то числа берутся от 0 до x. Этот объект можно использовать в циклеfor
или преобразовать в последовательность. Пример:
s = tuple(range(0, 5, 2))
s == (0, 2, 4)
Специальные методы строк
https://docs.python.org/3/library/stdtypes.html#string-methods
Строки имеют ряд методов, доступных только для строк. Ниже перечислены некоторые, за полным списком — в документацию.
s.capitalize()
— Возвращает копию строки s, в которой первое слово начинаются с большой буквы, а остальные становятся маленькимиs.center(w, c)
— добавляет строке s символов c (или пробелов, если c не указан) слева и справа, чтобы строка-результат была длиной не меньше числа w, при этом содержание s находилось по центру. Пример:
'Winter'.center(10, '=')
→'==Winter=='
'Winter'.center(10)
→' Winter '
s.endswith(r)
— проверка, кончается ли строка s подстрокой r. Пример:
'Python is awesome'.endswith('some')
→True
s.startswith(r)
— аналогично, проверка, начинается ли строка s с подстроки rs.find(r, start, end)
— поиск подстроки r в строке s, начиная с символа номер start и заканчивая символом номер end. start и end могут отсутствовать, тогда поиск идёт по всей строке. Результат функции — индекс первого символа найденной подстроки, или -1, если подстрока не найдена.- Разные тесты:
s.isalphanum()
— состоит ли строка только из букв и цифр,s.isdigit()
— состоит ли строка только из цифр,s.isidentifier()
— является ли строка корректным (для Python) именем, и так далее, их довольно много. Все эти методы возвращаютTrue
илиFalse
. s.join(m)
— здесь m — последовательность. В результате получается строка, состоящая из строковых представлений элементов m, разделённых содержимым s. Например:
'; '.join([1, 2, 3])
→'1; 2; 3'
s.split(sep)
— разбивает строку на подстроки по разделителю sep и возвращает их как список. Пример:
'bob=alice=charlie'.split('=')
→['bob', 'alice', 'charlie']
s.zfill(w)
— добивает строку s нулями в начале, пока её длина не станет w. При этом если строка начинается с + или -, сохраняет знак первым символом. Пример:
'-13'.zfill(5)
→'-0013'
'13'.zfill(5)
→'00013'
- И так далее. Строки умеют странное.
Словари
https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
Они же map'ы, они же ассоциативные массивы. Содержат пары вида ключ: значение. Ключём может быть любой объект, для которого определён хэш — числа, строки и т. д. Чаще всего используют строки. Значениями могут быть вообще любые объекты.
Словарь — модифицируемый объект.
Тип называется dict
.
Создание словаря
{}
— пустой словарь.{'one': 1, 2: 'two'}
— словарь из двух элементов.dict([('one', 1), (2, 'two')])
— тот же словарь, сконструированный из списка кортежей (см. функциюzip
выше).
Операции и методы словаря
len(d)
— количество элементов в словаре d.d[key]
— значение, соответствующее ключу key. Если нет такого ключа, выбрасывает исключениеKeyError
.d[key] = x
— присваивает элементу с ключём key значение x, или добавляет элемент, если его ещё не было.del d[key]
— удаляет элемент с ключём key.key in d
— возвращаетTrue
, если в словаре d есть элемент с ключём key.key not in d
— то же, чтоnot (key in d)
.d.clear()
— очистка словаря.d.copy()
— возвращает копию словаря (новый объект).d.get(key, default)
— то же, чтоd[key]
, но если элемент не найден, возвращаетdefault
(илиNone
, если default не указано) вместо выбрасывания исключения.d.update(k)
— добавляет пары ключ-значение из словаря k в словарь d. Если какие-то ключи из k уже есть в d, происходит замена значений.d.keys()
,d.values()
— возвращают ключи и значения в виде последовательностей, соответственно.- И это не все. См. документацию.
Генераторы списков (list comprehension)
https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
Они же списочные выражения. Это возможность генерировать списки по определённой закономерности.
Синтаксис: [выражение for имя in итер if условие]
Причём блоки for...in и if могут неоднократно повторяться.
То же самое справедливо для словарей. Пример:
{x: x ** 2 for x in range(100) if x % 2 == 0}
(это словарь, в котором числа соответствуют своим квадратам, причём только чётные числа).
Простой ввод-вывод
print(a, b, c...)
— выводит строковое предстваление всех своих аргументов на консоль. Подробное описание: https://docs.python.org/3/library/functions.html#print.input(p)
— выводит на консоль приглашение p (строку), и ждёт пользовательского ввода (до конца строки, то есть нажатия Enter). Возвращает введённую строку (без символа '\n' в конце).
Файловый ввод-вывод
Работа с файлами происходит через файловые объекты.
Создание файлового объекта
open(name, mode)
— открывает файл с именем name (строка) в
режиме mode и возвращает соответствующий ему файловый объект. Если
mode не указан, предполагается 'r' — чтение файла. Список режимов тут:
https://docs.python.org/3/library/functions.html#open.
Основные режимы: 'r'
— чтение, 'w'
— запись, 'a'
— добавление в конец. Для двоичных файлов, соответственно, 'rb'
, 'wb'
, 'ab'
.
Пример: f = open('input.txt', 'r')
.
Закрытие файла
Закрытие происходит при уничтожении файлового объекта, либо прямым вызовом метода f.close()
у файлового объекта f.
Текстовые файлы
https://docs.python.org/3/library/io.html#module-io
Текстовый файл — это итерируемый объект, возвращающий свои строки. По нему можно ходить циклом for, или преобразовать в последовательность.
Методы:
f.readline()
— читает очередную строку файла и возвращает её (с символом конца строки в конце). Если достигнут конец файла, возвращает пустую строку. Совсем пустую, длины 0.f.readlines()
— читает весь файл в список строк. То же самое, что list(f). Не используйте этот метод без необходимости, лучше циклfor
.f.read(n)
— читает как минимум n байт из файла, или весь файл до конца, если n не указана. Возвращает прочитанное в виде строки.f.tell()
— возвращает текущую позицию в файле.f.seek(n)
— ставит текущую позицию в файле на позицию n (0
— начало файла, либо используйте результатf.tell()
).f.writelines(lines)
— пишет строки из списка lines в файл. Не добавляет'\n'
в конце строк, так что они уже должны содержать'\n'
.f.write(x)
— пишет в файл строку x.
Синтаксис Python-программы
Программа записывается в файл (обычно с расширением «.py») построчно. Разделителем инструкций является конец строки файла. Если строка заканчивается на \ (бэкслэш), то она соединяется со следующей, так можно разбивать длинные инструкции на несколько строк файла.
Блоки кода выделяются отступом от начала строки. Отступ может ставиться как пробелами, так и символами табуляции, но предпочтительнее пробелы. Стандартным считается отступ в 4 пробела на каждый уровень вложенности блоков. Если в пределах одного блока отступ изменяется, интерпретатор останавливается с сообщением о синтаксической ошибке (IndentationError
).
Управляющие конструкции
https://docs.python.org/3/tutorial/controlflow.html#more-control-flow-tools
Условие
if условие-1:
блок-1
elif условие-2:
блок-2
else:
блок-3
Блоков elif
может быть несколько, а может и ни одного. Блока else
тоже может не быть.
Условный оператор как выражение
выражение1 if условие else выражение2
Это аналог триарного оператора ? : из С, Java и подобных языков. Работает так: если условие выполняется (True
), то результат выражения — выражение1
, а если нет — выражение2
.
Пример:
code = inp_code if inp_code is not None else def_code
Это аналогично следующему коду:
if inp_code is not None:
code = inp_code
else:
code = def_code
Эквивалент в С: code = (inp_code != NULL) ? inp_code : def_code;
Циклы
while условие:
блок-1
else:
блок-2
for переменная in итерируемый-объект:
блок-1
else:
блок-2
Циклы могут быть прерваны оператором break
. Кроме того, есть
оператор continue
, который прерывает текущую итерацию и начинает
следующую.
Блок кода после else
выполняется, если цикл завершился нормально, а
не с помощью оператора break. Этого блока может не быть.
Итерируемым объектом для цикла for
может быть любая
последовательность (строка, список, кортеж, словарь), а так же результат таких
функция, как zip()
, range()
. Файлы и некоторые другие объекты тоже
являются итерируемыми.
Функции
https://docs.python.org/3/tutorial/controlflow.html#defining-functions
Определение функции:
def имя-функции(параметры):
блок-кода
Параметры — имена формальных параметров через запятую.
Для возврата значения из функции служит оператор return:
return значение
Если функция завершилась не вызовом return
, она возвращает None
.
Можно указывать аннотации для типов параметров и возвращаемого значения. Они носят документационный характер и никак не влияют на работу интерпретатора, то есть при вызове функции не проверяется, корректные ли типы у параметров. Синтаксис:
def имя-функции(п1: тип1, п2: тип2...) -> тип-результата:
блок-кода
Вообще, благодаря утиной типизации проверка типов параметров и не
нужна. Просто работайте с пришедшими в функцию объектами, ведь, скажем,
итерируемый объект может быть и списком, и результатом функции range
, и
файлом, и чем угодно ещё. Пусть ваша функция будет универсальной. Если
что-то пойдёт не так — просто будет выброшено исключение.
Функции являются объектами первого рода, то есть их можно присваивать перменным, хранить в списках, кортежах и словарях, передавать как параметр в другие функции и так далее.
Сравните:
def f(x):
return x + 1
z = f # z содержит саму функцию f
t = f(1) # t содержит результат вызова f при x=1
Параметры функций
Напомним синтаксис объявления функции:
def имя(параметры):
тело
Параметры — это имена, перечисленные через запятую. Параметрам можно указывать их значения по умолчанию:
def f(x, y, z=0):
В таком случае можно будет вызывать функцию f как от трёх арументов (f(1, 1, 3)
), так и от двух (f(1, 1)
), во втором случае аргумент z будет равен 0. Очевидно, что после параметров по умолчанию не могут идти параметры без значений по умолчанию.
Функции от перменного числа аргументов
Некоторые функции могут принимать любое число параметров. Например, стандартная функция print()
. Можно в своём коде объявить функцию от переменного числа аргуметов:
def f(*args):
for arg in args:
print(arg)
Эта функция выводит все свои аргументы на экран, по одному в строке. Параметр со звёздочкой получит в качестве значения все аргументы функции с этой позиции, в виде кортежа.
Функции с keyword-аргументами
Как известно, значения параметров функции при вызове можно задавать в любом порядке, используя их имена (так называемые keyword-аргументы, или kw-аргументы):
sorted(array, reverse=False)
Чтобы создать функцию, принимающую любые kw-аргументы, применяется следующий синтаксис:
def f(**kwargs):
for k in kwargs:
print(k, '=', kwargs[k])
Аргумент с двумя звёздочками становится словарём, содержащим все именованные аргументы с этого места. Можно сочетать все способы объявления функции:
def my_function(x, y, z=0, *args, **kwargs):
...
Распаковка параметров
Если у нас есть кортеж (или список, или другая последовательность) с данными, содержимое этого кортежа можно использовать как набор аргументов функции. Синтаксис:
x = (1, 2, 1, False)
some_function(*x)
some_function(x[0], x[1], x[2], x[3])
Последние две строки примера эквивалентны.
Лямбда-выражения
https://docs.python.org/3/tutorial/controlflow.html?highlight=lambda#lambda-expressions
Лямбда-выражения можно использовать как локально определённые безымянные функции, состоящие из одного выражения. Им можно назначать имена, либо передавать как параметр в другую функцию.
Синтаксис:
func = lambda арг, арг, арг...: выражение
Аргументов может быть сколько угодно.
Пример. Лямбда-функция, возвращающая сумму аргументов:
summator = lambda x, y: x + y
print("Сумма 2 и 3:", summator(2, 3)) # Использование
Исключения
https://docs.python.org/3/tutorial/errors.html
Работают так же, как в большинстве языков. Практически все исключения унаследованы от класса Exception.
Блок обработки исключений:
try:
код-бросающий-исключение
except Исключение1 as переменная:
обработка-исключения-1
except Исключение2:
обработка-исключения-2
else:
код-если-не-было-исключений
finally:
код-который-всегда-выполнится
Если мы указали тип as переменная
, мы можем обратиться к полю args этой переменной:
e.args
— кортеж дополнительных аргументов исключения, зависит от его типа.
Пример:
try:
f = open("some_file.txt")
except OSError as e:
print("Ошибка:", ", ".join(e.args))
Некоторые классы исключений имеют дополнительные поля и/или методы. Подробнее смотрите в документации.
Типы стандартных исключений
https://docs.python.org/3/library/exceptions.html#bltin-exceptions
LookupError
— ошибка поиска элемента. Подклассы:IndexError
KeyError
ArithmeticError
— арифметическая ошибка. Подклассы:OverflowError
ZeroDivisionError
FloatingPointError
- и так далее
AttributeError
— обращение к несуществующему аттрибутуTypeError
— тип аргумента не подходит. Бросается в ситуациях, когда дейстиве не имеет смысла. Например, нельзя сложить строку и число, или разделить строку на строкуValueError
— ошибочное значение параметра. Например, нельзя создать диапазон с шагом 0 (с помощьюrange()
)ImportError
— ошибка импорта: например, модуль не существуетOSError
— ошибка ОС: например, недостаточно прав на доступ.RuntimeError
— прочие ошибки времени выполнения
NameError
, SyntaxError
, IndentationError
— ошибки в коде программы (неверный идентификатор, ошибка синтаксиса, неправильный отступ в блоке). Строго говоря, ловить их бессмысленно, но формально это тоже исключения, только бросаемые интерпретатором
Выбрасывание исключения
https://docs.python.org/3/tutorial/errors.html#raising-exceptions
Исключение может иметь любой тип, но желательно, чтобы он был унаследован от стандартного класса Exception. В идеале, не следует придумывать свои типы для исключений и пользоваться стандартными, дабы не плодить сущности. Кончено, кроме ситуации, когда ни один стандартный тип не подходит (или неудобен).
Синтаксис выбрасывания исключений:
raise Новый-объект(аргумент, аргумент...)
Аргументы в указанном порядке попадают в поле args
исключения (если речь идёт о наследнике класса Exception
).
Если вы внутри блока except хотите повторно выбросить пойманное исключение, можно использовать инструкцию raise без параметра:
raise
Пример выбрасывания исключения:
if index >= array_size:
raise IndexError('Index out of range', index)
Модули
Модуль — это Python-файл, содержащий некие классы, функции и переменные. Модули объединены в пакеты, а те, в свою очередь, в иерархию пакетов. Можно рассматривать их как библиотеки.
Подключение модуля
Простейший случай:
import имя-модуля, имя-модуля...
В результате в текущем пространстве имён создаётся объект имя-модуля типа module, содержащий в качестве полей все функции, классы и переменные этого модуля. Обращаться к ним можно через точку, как обычно:
import random
z = random.randint(1, 100)
Можно импортировать имена из модуля в локальное пространство имён:
from модуль import имя, имя, имя...
После этого указанные имена становятся доступны в локальном пространстве имён без префиков. Например:
from random import randint
z = randint(1, 100)
Можно импортировать имена из модуля под другими именами:
from random import randint as random_integer_number
z = random_integer_number(1, 100)
z = randint(1, 100) # Тут будет NameError
На вызове randint
в этом примере возникнет NameError
, так как имени randint
не существует, ведь мы переименовали функцию randint
при импорте.
Ещё можно импортировать весь модуль в локальное пространство имён:
from модуль import *
Никогда так не делайте. Просто поверьте мне: явное лучше неявного.
Пакеты
Пакет — это каталог с файлами модулей. Пакет обязательно содержит файл с именем __init__.py
(двойные символы подчёркивания в имени, этот файл может быть пустым). Пакеты могут быть вложенными (это ж каталоги), но каждый пакет обязательно содержит __init__.py
.
Вложенные пакеты образуют пространства имён, модули из них импортируются по полному пути, через точку в качестве разделителя:
from django.contrib.auth.models import User
То есть в пакете (то бишь каталоге) django
есть пакет (каталог) contrib
, в нём — каталог (пакет) auth
, в нём модуль (файл) models
, а в модуле (в файле) — класс User
, который мы импортируем.
Модули интерпретатор ищет в каталоге, в котором находится текущий файл скрипта, в каталогах, указанных в переменной окружения PYTHONPATH
и в переменной path модуля sys (sys.path
). Последняя является списком строк с именами каталогов.
Да, sys.path
можно модифицировать, не забудьте про import sys
.
Переменная __name__
В каждом модуле есть глобальная переменная __name__
, содержащая имя модуля (двойные символы подчёркиванья).
Однако для файла, с которого началось выполнение (который был запущен с помощью интерпретатора напрямую, а не импортирован), __name__
содержит специальное значение — строку '__main__'
.
Так можно узнать, запустили наш модуль на исполнение, или импортировали:
if __name__ == '__main__':
do_run() # Нас запустили как программу
else:
do_something_else() # Нас импортировали