Содержание
Краткая памятка по трансляции Python-программ
- Исходный код Python проходит лексический анализ и парсинг.
- Создается абстрактное синтаксическое дерево (AST).
- AST компилируется в байт-код (файлы.pyc).
- Виртуальная машина CPython исполняет байт-код.
- JIT-компиляторы (как в PyPy) могут преобразовывать байт-код в машинный код.
- GIL ограничивает параллельное выполнение потоков.
- Альтернативные реализации (Jython, IronPython) используют свои виртуальные машины.
- Инструменты вроде Nuitka компилируют Python напрямую в машинный код.
- Динамическая типизация замедляет выполнение из-за проверок типов.
- Оптимизация кода (например, использование встроенных функций) ускоряет выполнение.
Язык программирования Python
Python представляет популярный высокоуровневый язык программирования, который предназначен для создания приложений различных типов. Это и веб-приложения, и игры, и настольные программы, и работа с базами данных. Довольно большое распространение питон получил в области машинного обучения и исследований искусственного интеллекта.
3.14
Впервые язык Python был анонсирован в 1991 году голландским разработчиком Гвидо Ван Россумом. С тех пор данный язык проделал большой путь развития. В 2000 году была издана версия 2.0, а в 2008 году — версия 3.0. Несмотря на вроде такие большие промежутки между версиями постоянно выходят подверсии. Так, текущей актуальной версией на момент написания данного материала является, которая вышла в октябре 2026 года.
- Скриптовый язык. Код программ определяется в виде скриптов.
- Поддержка самых различных парадигм программирования, в том числе объектно-ориентированной и функциональной парадигм.
- Интерпретация программ. Для работы со скриптами необходим интерпретатор, который запускает и выполняет скрипт. Выполнение программы на Python выглядит следующим образом. Сначала мы пишим в текстовом редакторе скрипт с набором выражений на данном языке программирования. Передаем этот скрипт на выполнение интерпретатору. Интерпретатор транслирует код в промежуточный байткод, а затем виртуальная машина переводит полученный байткод в набор инструкций, которые выполняются операционной системой. Здесь стоит отметить, что хотя формально трансляция интерпретатором исходного кода в байткод и перевод байткода виртуальной машиной в набор машинных команд представляют два разных процесса, но фактически они объединены в самом интерпретаторе.
- Портативность и платформонезависимость. Не имеет значения, какая у нас операционная система — Windows, Mac OS, Linux, нам достаточно написать скрипт, который будет запускаться на всех этих ОС при наличии интерпретатора
- Автоматическое управление памяти
- Динамическая типизация
Поддержка самых различных парадигм программирования, в том числе объектно-ориентированной и функциональной парадигм.
Интерпретация программ. Для работы со скриптами необходим интерпретатор, который запускает и выполняет скрипт.
Выполнение программы на Python выглядит следующим образом. Сначала мы пишим в текстовом редакторе скрипт с набором выражений на данном языке программирования. Передаем этот скрипт на выполнение интерпретатору. Интерпретатор транслирует код в промежуточный байткод, а затем виртуальная машина переводит полученный байткод в набор инструкций, которые выполняются операционной системой.
Здесь стоит отметить, что хотя формально трансляция интерпретатором исходного кода в байткод и перевод байткода виртуальной машиной в набор машинных команд представляют два разных процесса, но фактически они объединены в самом интерпретаторе.
Портативность и платформонезависимость. Не имеет значения, какая у нас операционная система — Windows, Mac OS, Linux, нам достаточно написать скрипт, который будет запускаться на всех этих ОС при наличии интерпретатора
Python — очень простой язык программирования, он имеет лаконичный и в то же время довольно простой и понятный синтаксис. Соответственно его легко изучать, и собственно это одна из причин, по которой он является одним из самых популярных языков программирования именно для обучения. В частности, в 2014 году он был признан самым популярным языком программирования для обучения в США.
Python также популярен не только в сфере обучения, но в написании конкретных программ в том числе коммерческого характера. В немалой степени поэтому для этого языка написано множество библиотек, которые мы можем использовать.
Кроме того, у данного языка программирования очень большое сообщество программистов, в интернете можно найти по данному языку множество полезных материалов, примеров, получить квалифицированную помощь специалистов.
Пакеты и библиотеки
Интерпретатор Python сопроваждается достаточным функционалом, который позволяет создавать приложения на этом языке. Тем не менее этого функционала может оказаться недостаточно для ряда задач. Но в виду большого сообщества разработчиков на этом языке по всему миру также имеется большая экосистема различных пакетов и библиотек, которые можно использовать для различных целей. В разделе языка Python на сайте будут рассмотрены некоторые из этих библиотек. Перечислю основные из них.
- Tkinter
- PyQt / PySide
- wxPython
- DearPyGui
- EasyGUI
- Kivy
- Toga
- Django
- Flask
- FastAPI
- Pylons
- Bottle
- CherryPy
- TurboGears
- Nagare
- Selenium (для тестирования веб-приложений)
- Flask
- FastAPI
- Pylons
- Bottle
- CherryPy
- TurboGears
- Nagare
- robotframework
- pywinauto
- Lettuce
- Behave
- Requests
- OpenPyXL (Excel)
- lxml (XML)
- ReportLab / borb (PDF)
- pdfrw / PyPDF2 (PDF)
- Pandas (CSV и Excel)
- Pandas
- SciPy
- PyTorch
- Matplotlib
- Theano
- Tensorflow
- OpenCV
- Scikit-Learn
- Keras
- NumPy
Тесты по числам
X 0x 0X 0123456789ABCDEF 0x7F 0XDD5A -0xfF9
В шестнадцатеричной системе счисления запись целого числа должна начинаться с нуля и латинской буквы в верхнем или нижнем регистре (т.е. или), после чего должны идти символы последовательности, представляющих данную систему счисления. При этом буквы также разрешается использовать в любом регистре. Например,,,. Если будут использованы символы не входящие в данный диапазон, интерпретатор сгенерирует сообщение об ошибке.
3.15 + 6 = 9.15
Первое число было округлено до двух знаков после запятой, а второе до целой части (по умолчанию). Поэтому и получили.
2.12. Python
Какая из встроенных функций может быть использована для нахождения модуля числа?
10n E e E
В Пайтон допустима запись вещественных чисел в экспоненциальной форме. При этом для представления степени используется латинская буква в верхнем или нижнем регистре (т.е. или), следующий за ней необязательный знак плюс или обязательный знак минус, а также сам показатель степени в виде положительного целого числа или нуля. Кроме того, ведущий ноль разрешается опускать.
Тесты по строкам
Не забываем, что строки относятся к неизменяемому типу данных, поэтому изменить их непосредственно не получится. Но всегда можно получить измененную копию строки и заменить ею хранящуюся в переменной исходную строку.
3.4.
Какая последовательность символов представляет собой экранированную последовательность, соответствующую переводу строки?
Экранированная последовательность \n \u000A \» \u0022
– это специальная последовательность символов, начинающаяся со знака обратного слеша, которая обозначает символ, не всегда представимый внутри строки другими способами. Например, или – перевод строки, или – двойная кавычка и т.д.
‘2’ ‘5’*2 ’55’
Здесь строка была сперва приведена к целому чилу. Поэтому в результате умножения была получена строка.
‘6’ 5
Все символы строки нумеруются, начиная с нуля. Поэтому на экран будет выведен символ строки, т.е. символ с индексом.
0 4 ‘5’
Здесь нужно получить срез строки, начиная с первого символа с индексом и заканчивая символом с индексом (это).
r’D:\text’ + ‘\\’ r’D:\text\\'[:-1] ‘D:\\text\\’
Неформатированные строки не могут заканчиваться неэкранированным символом обратного слеша, т.к. он будет экранировать кавычки в конце строки. В таких случаях можно добавить его отдельно при помощи конкатенации (например,), продублировать и затем удалить при помощи среза (например,) или не использовать подавление вообще, экранировав все слеши в обычной строке (например,).
3.11.
Какой из методов используется для соединения подстрок в одну строку по заданному разделителю?
‘3’ 3 -3 -1 s[3::3]
Символ строки доступен по положительному индексу, т.к. нумерация символов начинается с нуля, а также по отрицательному индексу, если получать доступ к нему с конца строки (в этом случае нумерация начинается с). Также данный символ является первым и единственным символом среза строки, поскольку для получения второго элемента среза у строки не хватает длины.
print(‘Гостиница \’Орбита\’, 3 звезды.’)
Использование кавычек любого разрешенного типа внутри строковых литералов, заключенных в кавычки того же типа, разрешается при условии предварительного экранирования их при помощи обратного слеша. В нашем случае правильно было бы написать. Также можно было бы использовать двойные кавычки.
s = s[2] + s[5] ‘cc’ 8
После выполнения второй инструкции в переменной будет храниться строка длиной в два символа. Поэтому попытка получения символа строки с индексом приведет к ошибке.
3.16.
Какой из методов используется для удаления пробельных символов с начала и конца строки?
‘1 11 111’
После выполнения инструкций замены в переменной будет храниться строка длиной в восемь символов.
3.18. s Питоне
Как проверить, является ли некоторая строка допустимым в идентификатором?
s_2[0] = ‘г’
Помним, что строки неизменяемы. Поэтому инструкция приведет к ошибке.
x f {y} {x + y}
Здесь находится вне фигурных скобок, поэтому считается интерпретатором за обычный символ строки. А вот выражения внутри фигурных скобок -строк вычисляются, поэтому при выводе и были заменены соответствующими им значениями.
Тесты по спискам
Не забываем, что списки, в отличие от строк и кортежей, мы можем изменять непосредственно.
[‘1’, ‘2’, ‘3’] [(1, 2, 3)]
– список из трех строковых элементов, а – список из одного элемента в виде кортежа.
[1, 1, 1] li*3 3 li + li + li
В первой инструкции был создан список с одним элементом. Во второй инструкции к нему был присоединен список, полученный в результате операции умножения (объединение с самим собой раза, т.е.).
-1
При использовании отрицательных индексов отсчет элементов ведется с конца списка. При этом отсчет индексов начинается с, а не с нуля.
[0:-4] -4
Берем срез, т.е. начиная с первого элемента и заканчивая элементом с индексом, но не включая его в конечный результат.
При использовании отрицательного шага срез берется в обратном направлении, т.е. выборка элементов для среза ведется с конца списка.
elem
Третий вариант удаляет из списка первый попавшийся элемент, имеющий значение. Последний вариант удаляет все элементы из списка.
‘cd’ li[2] li[-3] ‘d’
Для доступа к элементам списка, которые сами являются последовательностями, используется цепочка квадратных скобок с указанием требуемых индексов. В нашем случае доступ к строке можно получить через или же через, если считать с конца списка. Вторые квадратные скобки дают доступ уже к самому символу строки.
join() append()
Метод имеется у строк, у списков такой метод отсутствует. В последнем случае метод не объединит списки, а добавит второй список в первый в качестве нового элемента.
li_1 li_2
Обе ссылки и ссылаются на один и тот же изменяемый объект (список) в памяти и полное или частичное изменение этого объекта доступно через любую из них. Соответственно через любую из ссылок видны и последствия таких изменений.
Самостоятельно подумайте над результатами выполнения всех предложенных инструкций и проверьте ответы в интерпретаторе.
(iterable) iterable li li[len(li):] = iterable
– добавляет элементы из итерируемого объекта в конец списка (тоже самое что и).
Здесь в конец списка добавляются элементы итерируемого объекта. Число так добавить не получится.
Тесты по кортежам
Не забываем, что кортежи относятся к неизменяемому типу данных, поэтому изменить их непосредственно не получится. Но всегда можно получить измененную копию кортежа и заменить ею хранящийся в переменной исходный кортеж.
В отличие от списков кортежи неизменяемы, т.е. добавлять в них новые элементы, а также заменять или удалять их запрещено. В тоже время кортежи упорядоченны, т.к. каждый элемент пронумерован целочисленными индексами.
‘-7-8-9-10’
Здесь был получен доступ к строке вложенного кортежа и взят ее срез с использованием отрицательного шага.
Тесты по словарям
в) г)
– ошибка, т.к. в этом случае для ключей нужно использовать идентификаторы, а не строки, – здесь наоборот.
d = {1: ‘a’, ‘2’: [‘b’, {‘c’: 3}], (5, ‘6’): (‘f’, ‘g’)} print(len(d))
Тесты по множествам
Ответ. а) б) в)
коллекции неизменяемых объектов, изменяемые коллекции объектов, неупорядоченные коллекции объектов.
Сами множества изменять разрешается, но вот их элементы должны быть неизменяемыми типами данных. Поэтому мы можем добавить в качестве элемента число, но не список. Кроме того, множества неупорядоченные коллекции. Поэтому доступ к его элементам отсутствует как по индексам, так и по ключам.
7.6. {‘a’, ‘b’, ‘c’} {‘b’, ‘c’, ‘d’}
Даны два множества и. Какое из множеств является их пересечением?
Операция пересечения предполагает получение нового множества с элементами, которые есть сразу у всех объединяемых множеств.
Операция объединения предполагает получение нового множества с элементами, которые есть хотя бы у одного из объединяемых множеств.
pop() KeyError
Метод у множеств не принимает в качестве аргумента элемент. Он просто удаляет и возвращает произвольный элемент множества или, если множество окажется пустым, возбуждает исключение.
Не забываем, что множество представляет собой неупорядоченную коллекцию объектов, а значит, отсортировать его не получится.
st_1 None
Элемент в множество конечно же добавлен будет. Однако метод хоть и изменяет свое множество, но возвращает не его, а значение.
Тесты по логическому типу
True 1 False 0
Булевы константы можно использовать в математических выражениях на равных с числами, оперируя как, а как.
8.5.
Какой оператор позволяет проверить одновременное выполнение сразу нескольких условий?
11 > 0 is True (11 > 0) and (0 is True) expr_1 op expr_2 op expr_3 (expr_1 op expr_2) and (expr_2 op expr_3)
эквивалентно. Это касасется и других комбинированных условий сравнения: в общем виде эквивалентно.
3 True
Здесь интерпретируется как, поэтому правый операнд уже не вычислялся. Вместо этого был просто возвращен результат вычисления левого операнда (см. подробнее в учебнике).
not True False
Здесь наоборот, интерпретируется как, поэтому был возвращен результат вычисления правого операнда, т.е. вызов функции (см. подробнее в учебнике).
Тесты на приведение типов
Все неповторяющиеся элементы итерируемого объекта, т.е. числа переданного списка, стали элементами множества (коллекции уникальных объектов).
1 + 1.0
После преобразования получим, поэтому результатом будет вещественное число (более общий тип).
Тесты по инструкции присваивания
10.1.
Какой из представленных вариантов соответствует позиционной инструкции присваивания?
Позиционное присваивание связывает объекты последовательностей справа от оператора присваивания с именами, перечисляемыми слева от него. При этом присваивание выполняется слева направо согласно местоположениям имен и соответствующих им объектов.
x 10 y x 20 10 y print(y)
Сперва переменная хранила ссылку на объект целого числа в памяти. Далее, в результате присваивания, ссылку на объект получила еще и переменная. В результате на неизменяемый объект в памяти стало указывать уже две ссылки. Но ниже переменной было присвоено новое значение, точнее новая ссылка на другой объект целого числа. Однако объект числа при этом из памяти не удалился, ведь ссылка на него осталась еще в переменной, что и подтвердил вывод инструкции.
10.3.
Какой оператор используется для присваивания значения переменной внутри выражения?
В отличие от второго теста, здесь переменные ссылаются на один и тот же изменяемый объект. Поэтому все изменения в этом объекте (списке) будут отслеживаться сразу всеми переменными, хранящими на него ссылку.
((3, 4), (1, 2))
В результате позиционного присваивания происходит обмен значениями за счет создания временного кортежа.
y x[0] = 10 x
В отличие от четвертого теста, здесь переменные ссылаются на разные объекты в памяти, т.к. переменной присваивается ссылка на совершенно другой объект в памяти, создаваемый для хранения копии исходного списка. Поэтому инструкция изменяет только тот объект в памяти, на который ведет соответствующая переменной ссылка.
1 2 [3, 4, 5] a 7 1 + 2 + 4
В результате использования в первой инструкции расширенного синтаксиса распаковывания последовательностей в переменных будут храниться значения, и. Во второй инструкции в результате комбинированного присваивания в переменной будет храниться число ().
Расширенный синтаксис распаковывания последовательностей допускает использование в позиционном присваивании только одной переменной со звездочкой.
Тесты по условной инструкции
elif else
Блоков может быть как несколько, так и вообще ниодного. Блок может отсутствовать, но если он используется, то только один.
11.3.
Какой из представленных вариантов можно отнести к верному формату представления условной инструкции?
г) if/else
Вариант соответствует верному формату трехместного выражения. Но в тесте требуется найти верный формат именно инструкции.
11.4.
Сколько условий допускается для проверки внутри одной условной конструкции?
11.6. if
Какой из предлагаемых операторов можно использовать для инвертирования условия в инструкции?
res = 0 if []: res += 1 if False: res += 1 if not None: res += 1 if -1: res += 1 print(res)
False -1 True not None True if
Нужно вспомнить особенности приведения к логическому типу: пустой список приводится к, а вот число к значению. Кроме того, конвертируется в. В результате из четырех блоков выполнится только два.
s = » if s: if ‘a’ in s: res = True else: res = False else: res = None print(res)
False else
Опять же, нужно вспомнить особенности приведения к логическому типу: пустая строка приводится к. Следовательно будет выполнен блок.
Тесты по циклам for и while
12.2.
Какой из следующих вариантов можно использовать для организации бесконечного цикла?
range() for
Функция в нашем случае вернет объект с последовательностью из трех чисел от нуля до двух. А цикл выведет их на экран с противоположным знаком.
x y
Здесь осуществляется итерация по двум элементам (кортежам) списка. При этом используется расширенный синтаксис распаковывания последовательностей. В результате на каждом витке первый элемент целевого кортежа присваивается переменной, а оставшиеся собираются в список, который присваивается переменной. Далее значения переменных просто выводятся на экран.
break
Счетчик стартует с единицы. Цикл прерывается оператором и не достигает очередной инструкции вывода, как только значение счетчика достигнет четырех.
k = 0 while True: if k > 5: break if k == 3: k += 1 continue print(k, end=’ ‘) k += 1
break 3 if continue
Счетчик стартует с нуля. Цикл прерывается оператором и не достигает очередной инструкции вывода, как только значение счетчика достигнет шести. При этом по ходу цикла значение пропускается из-за условной инструкции и оператора внутри.
12.10.
Какой из следующих операторов можно использовать для выполнения блока кода после завершения цикла?
continue break pass
Операторы и используются внутри циклов. А – это вообще пустая инструкция-заполнитель, которая может использоваться внутри циклов вместо тела.
k = 4 while k: k -= 1 print(k, end=’ ‘) if k>2: continue else: print(0)
if continue else
Счетчик стартует с четырех. Внутри цикла он сразу же уменьшается на единицу, а новое значение выводится на экран. Поскольку условная инструкция с оператором внутри используется позже, она никак и не повлияла на вывод значений. После обнуления счетчика, цикл завершается без ошибок, а значит срабатывает блок инструкций, т.е. выводится еще один ноль.
while for n -1
Счетчик основного цикла стартует с одного. Внутри цикла сразу же начинает работать внутренний цикл, который выводит на экран все значения убывающей последовательности чисел от двух до нуля с шагом. А это всего два числа: два и один. Когда внутренний цикл завершается, счетчик основного цикла увеличивается на единицу. Далее проверяется условие равенства счетчика трем: по достижении этого значения внешний цикл завершает свою работу. А это значит, что внешний цикл повторяется всего два раза.
Различие с предыдущим тестов в том, что счетчик увеличивается после проверки условия на равенство его значения трем! Это и дает прирост количества итераций на единицу. Ответили неверно? Пройдитесь по итерациям еще раз.
Тесты на итерации и генераторы
13.1.
Какие из предложенных вариантов объектов относятся к итерируемым?
Строки хотя и относятся к неизменяемому типу данных, но дают доступ к своим символам. А вот пройтись по цифрам числа напрямую не получится.
13.2.
С помощью какой функции можно преобразовать итерируемый объект в итератор?
li_iter = iter([1, 2, 3]) next
Например,. Что касается встроенной функции, то она используется для получения следующего элемента полученного итератора.
next print
Встроенная функция используется для получения следующего элемента полученного итератора. Следовательно в ходе первого ее применения будет возвращен первый элемент итератора (на экран мы его не выводим), а в ходе второго вызова – второй элемент, который и будет выведен на экран функцией.
13.4.
Что произойдет, если попытаться получить элемент из итератора, который исчерпал все свои элементы?
iter
Остальные генераторы вернут множество, список и словарь, итераторы которых сперва придется получить при помощи функции.
g_1 = (x for x in range(2, 5)) g_2 = [x+1 for x in range(2, 5)] res = next(g_1) + next(g_2) print(res)
next iter(g_2)
К спискам не применима функция! Сперва нужно получить итератор с помощью функции, а затем уже получать элемент и находить сумму.
def f_2(n): for i in range(1, n+1): yield i gen = f_2(30) res = next(gen) + next(gen) + next(f_2(30)) print(res)
next(gen) next(f_2(30)) f_2
В первый раз вернет один, затем два. вернет один, т.к. каждый новый вызов функции создает новый объект итератора, а значит выдача элементов начинается заново.
Тесты по функциям
14.2. return
Что возвращает функция, в которой отсутствует инструкция?
None def func(): pass print(func())
Технически все равно будет возвращено. Проверить легко, использовав, например, вызов пустой функции в инструкции.
Ничего на экран выведено не будет, т.к. вызов функции осуществлен не был. Для этого нужно было к имени функции добавить скобки. А так в код программы было просто вписано имя, ссылающееся на объект ранее определенной функции, что вполне себе разрешено и ошибки не вызовет.
def my_func_1(): print(1, end=’ ‘) my_func_2() def my_func_2(): print(2, end=’ ‘) my_func_1()
Не забываем, что функции можно вызывать только после их объявления. Если ход выполнения скрипта не дошел до места определения функции, будет брошено исключение. Это касается и объявлений функций внутри условных инструкций.
14.5.
Какой из предлагаемых вариантов является допустимым способом передачи аргументов функции?
def f_1(a, b): return a + b def f_2(a, b=3, c=4): return a + b + c res = f_1(1, 2) + f_2(5, 5) print(res)
5 + 5 + 4
Ошибки здесь не будет, т.к. во второй функции используются значения по умолчанию, которые можно не указывать. Поэтому функцией будет возвращен результат вычисления выражения.
б) в)
Здесь нужно помнить, что первыми должны передаваться позиционные аргументы и только потом именованные. Это условие было нарушено вариантами и.
def f_1(a, b=2): return a + b def f_2(a, b, c=3): return a + b + c res = f_1(b=1, 2) + f_2(3, 4, c=5) print(res)
f_1(2, b=1) f_1(b=1, a=2) f_1(a=2, b=1) f_1(2, 1)
Опять же, первыми должны передаваться позиционные аргументы и только потом именованные. Правильно было бы написать,, или просто.
14.9.
Какой из предложенных вариантов заголовка функции может использоваться для определения функции, принимающей переменное число аргументов?
Первый вариант предполагает передачу произвольного числа позиционных аргументов (будут собраны в кортеж), второй – именованных (будут собраны в словарь), третий – и тех, и других.
Сама функция определена на первый взгляд верно. Однако передача ей даже двух аргументов при вызове будет возбуждать ошибку, т.к. операция сложения чисел с кортежами в Питоне не предусмотрена.
z
В первом варианте отсутствует передача обязательного именованного аргумента, а в последнем именованный аргумент передается перед позиционными, что также запрещено.
Определением функции подразумевается сбор всех позиционных аргументов в кортеж, а именованных в словарь.
global x
В теле функции интерпретатору сообщается о том, что необходимо использовать глобальную переменную (инструкция).
def func_1(): x = 20 def func_2(): nonlocal x x = 30 print(x) func_1()
x = 10 def func_1(): x = 20 def func_2(): global x x = 30 func_2() func_1() print(x)
func_1 x func_2 func_2 func_1
Внутри функции использутеся локальная переменная, а вот внутри вложенной функции – уже глобальная переменная. При этом функция не только определяется, но и вызывается при вызове родительской функции, что и приводит к изменению значения глобальной переменной.
Здесь объект анонимной функции присваивается переменной, а позже происходит обычный вызов функции, в которой один из аргументов имеет значение по умолчанию, а в теле используется разрешенное условное трехместное выражение. При этом следует помнить, что результатом операции деления целых чисел в любом случае будет вещественное значение.
а) б) в) г) Показать решение.
Варианты ответов: функция, которая вызывает саму себя внутри своего тела, функция, которая вызывает другую функцию внутри своего тела, функция, которая одновременно не имеет параметров и возвращаемого значения, рекурсивные функции в Пайтоне запрещены.
def factorial(n): if n == 0 or n == 1: return 1 else: return n*factorial(n — 1) print(factorial(5))
Если результат вызывает затруднения, еще раз внимательно почитайте пункт нашего учебника «Рекурсивные функции». После чего еще раз пройдитесь по всем этапам выполнения кода теста.
При вызове функции ей была передана строка, которая затем была в ходе этого вызова возвращена и объединена со строкой документации.
Тесты по ООП
15.2. ООП
Как называется механизм, который позволяет объединять данные и методы, работающие с этими данными, в единый объект, скрывая при этом детали реализации от пользователя?
15.6.
Укажите специальный метод, который используется для инициализации исходными данными вновь создаваемых экземпляров класса.
t_1.x == 1 t_2.x == 2
В конструкторе используется передача аргумента со значением по умолчанию. Поэтому, а.
Person() takes no arguments
В данном случае мы не определяли собственный конструктор класса, который принимал бы начальное значение возраста. Поэтому будет выведена ошибка «», уведомляющая нас о том, что передача аргументов конструктором не предусмотрена.
15.9. Python
Перечислите допустимые способы изменения значения атрибута объекта в.
object.__dict__
Получить доступ или посмотреть текущий набор атрибутов класса или экземпляра можно при помощи словаря атрибутов. При этом важно помнить, что словарь динамически изменяется в процессе изменения как количества доступных атрибутов, так и их значений.
age
На экран будет выведен словарь атрибутов объекта, имеющихся у него на момент обращения к словарю. Но атрибут удаляется лишь в следующей инструкции.
Не забываем, что атрибут данных класса доступен как из любого экземпляра класса, так и напрямую из объекта самого класса.
Test.x t.x == 3 Test.x == 1
Атрибут данных класса остался прежним, т.к. в конструкторе он переопределяется только для каждого конкретного вновь создаваемого экземпляра класса. Поэтому, а.
x t t.x Test Test.x
Даже после удаления атрибута в экземпляре при повторной попытке обращения к нему через интерпретатор не выдал ошибку, а сперва попытался отыскать одноименный атрибут в самом классе, вернув, как следствие, значение общедоступного атрибута.
15.16.
Какой декоратор используется для определения метода класса и позволяет работать с атрибутами класса, а не с атрибутами объекта?
@classmethod
Для объявления метода класса нужно записать декоратор на отдельной строке, предшествующей строке с определением целевого метода.
self cls
Следует помнить, что методы класса призваны обрабатывать данные самого класса, являющиеся общими сразу для всех экземпляров этого класса. Кроме того, если первый аргумент методов экземпляра при определении принято обозначать через и его нужно передавать явным образом при вызове через класс, то для первого аргумента методов класса принято использовать имя, не указывая его явным образом как при вызове из экземпляров, так и вызове через сам класс.
class Test: @classmethod def m_1(cls): return (1 if 1>0 else 0) obj = Test() print(obj.m_1() + Test.m_1())
Методы класса в общем случае доступны для вызова как через объект самого класса, так и через любой из его экземпляров.
15.19. Python
Перечислите верные варианты вызова статического метода в.
Методы, которые были объявлены статическими, в общем случае доступны для вызова как через объект самого класса, так и через любой из его экземпляров.
class Test: def m_1(): return (1 if 1>0 else 0) @staticmethod def m_2(): return (2 if 2>0 else 0) obj = Test() print(obj.m_1() + Test.m_2())
@staticmethod
Методы, просто объявленные внутри пространства имен класса, доступны посредством объекта класса, но недоступны для вызовов из экземпляров класса. Для этого нужно использовать декоратор.
15.21. Питоне
Как в принято обозначать атрибуты класса, предназначенные для внутреннего (служебного) использования?
_var
Атрибуты, предназначенные для внутреннего использования, принято начинать с одного символа подчеркивания (например,).
Атрибут, начинающийся с одного символа нижнего подчеркивания, остается доступен вне класса. Просто встретив такой атрибут, другой программист будет иметь в виду, что он не предназначен для публичного использования и в дальнейшем может быть даже удален без предварительного уведомления. В тоже время никто не запрещает изменять такой атрибут на свой страх и риск, надеясь, что это не повлияет на работоспособность класса.
__attr_name _Class__attr_name
Атрибут, начинающийся с двух символов нижнего подчеркивания, останется доступен внутри класса, но станет недоступен по такому имени за его пределами, т.к. вне класса имена атрибутов, начинающихся с двух символов подчеркивания, автоматически преобразуются интерпретатором из формата в формат.
__attr_name _Class__attr_name
Опять же, атрибут, начинающийся с двух символов нижнего подчеркивания, останется доступен внутри класса, но станет недоступен по такому имени за его пределами, т.к. вне класса имена атрибутов, начинающихся с двух символов подчеркивания, автоматически преобразуются интерпретатором из формата в формат.
15.25.
Какая из встроенных функций предназначена для создания управляемых атрибутов класса?
property(fget=None, fset=None, fdel=None, doc=None)
Результатом вызова встроенной функции является объект свойства, присваиваемый имени атрибута, которым требуется управлять, находящийся в области видимости класса, внутри которого она вызывалась, и наследующийся всеми экземплярами этого класса.
attr_x 3
При попытке изменения значения управляемого атрибута будет вызываться его метод-сеттер, постоянно присваивая атрибуту в качестве значения число.
class Test: @property def attr_x(self): return self.__x @attr_x.setter def attr_x(self, x): self.__x = x @attr_x.deleter def del_attr_x(self): del self.__x print(‘Атрибут удален!’) obj = Test() obj.attr_x = 7 del obj.attr_x
property ‘attr_x’ of ‘Test’ object has no deleter
Не забываем, что при использовании декораторов все методы должны иметь одно и то же имя, иначе интерпретатор возбудит исключение. В нашем случае мы получим ошибку удаления управляемого атрибута «».
15.28. method A B
Укажите верные варианты вызова метода суперкласса из его дочернего подкласса.
class A: def m_s(self): return 1 class B: def m_s(self): return 2 class C(B, A): def m_sub(self): return 3 obj = C() print(obj.m_s() + obj.m_sub())
class
Если подкласс наследует сразу несколько суперклассов с одинаковыми именами атрибутов, то им будет унаследовано значение атрибута того суперкласса, который перечисляется в заголовке инструкции первым.
class A: def set_1(self): self.__x = 1 return self.__x class B: def set_2(self): self.__x = 2 return self.__x class C(A, B): pass obj = C() print(obj.set_1() + obj.set_2())
_A__x _B__x
Благодаря наличию приставки из двух символов подчеркивания атрибуты остались доступны по короткому имени внутри классов, но стали недоступны извне, поскольку имена этих атрибутов были дополнены интерпретатором именами их классов до и.
15.31. Питоне
Имена магических методов в выделяются следующим образом:
а) б) в) г) Показать решение.
Варианты ответов: начинаются с одного символа подчеркивания, начинаются с двух символов подчеркивания, начинаются и заканчиваются одним символом подчеркивания, начинаются и заканчиваются двумя символами подчеркивания.
15.32.
Разрешается ли наследование магических методов, а также их переопределение в подклассах?
Все магические методы могут свободно наследоваться от суперклассов и переопределяться в подклассах, как и любые другие методы. Если же какой-то метод не реализован в классе, это лишь означает, что соответствующая ему операция не поддерживается данным классом, а попытка применения такой операции будет возбуждать исключение.
__add__ __sub__ __mul__ __truediv__ __mod__ __pow__ __and__ __or__ __getattr__ __setattr__ __delattr__ __getitem__ __setitem__ __delitem__ __len__ __bool__ __lt__ __gt__ __le__ __ge__ __eq__ __ne__ __iter__ __iadd__ __next__ __contains__ in __new__ __init__ __del__ __call__
Еще раз взгляните на наиболее часто используемые магические методы: (сложение), (вычитание), (умножение), (деление), (остаток от деления), (возведение в степень), (логическое И), (логическое ИЛИ), (обращение к атрибуту), (присваивание атрибуту), (удаление атрибута), (доступ к элементу по индексу, извлечение среза, итерации), (присваивание элементу по индексу или срезу), (удаление среза или элемента по индексу), (длина), (проверка логического значения), (меньше), (больше), (меньше или равно), (больше или равно), (равно), (не равно), (получение итератора), (комбинированный оператор сложения), (получение следующего элемента итератора), (оператор проверки на вхождение), (создание объекта), (конструктор), (деструктор), (вызов функции) и др.
__mul__ N
Поскольку магический метод был переопределен, операция умножения экземпляра класса на число стала возвращать сумму значений, а не их произведение. Вне контекста тестов делать так конечно же не следует.
15.35. abc Python
Какой базовый класс модуля стандартной библиотеки может быть использован для создания абстрактных классов в?
from abc import ABC, abstractmethod
Не забываем, что для использования класса его нужно сперва из модуля импортировать, например, инструкцией.
15.36. abc
Укажите верный декоратор модуля стандартной библиотеки, который может быть использован для создания абстрактных методов?
from abc import ABC, abstractmethod
Не забываем, что для использования декоратора его нужно сперва из модуля импортировать, например, инструкцией.
Абстрактный класс не может использоваться для создания экземпляров. Для этого он должен быть сперва унаследован, а все его абстрактные методы реализованы.
15.38.
Какой магический метод используется для определения деструктора?
Тесты на импорт, модули и пакеты
- домашний каталог программы, который в поиске участвует всегда, автоматически добавляясь в начало списка (если код запускается в интерактивном сеансе, в начало списка добавляется пустая строка);
- содержимое переменной окружения PYTHONPATH, если она задана;
- каталог стандартной библиотеки, который также всегда участвует в поиске;
- список каталогов, настроенных во время установки Python;
- содержимое любых файлов с расширением *.pht, если они используются.
*.pth Python site-packages Python site-packages site-packages
Если необходимость в импортировании модуля за пределами домашней папки и вне прописанных путей поиска все-таки возникает, разрешается использовать обычный текстовый файл с расширением, в котором нужно прописать добавляемые каталоги по одному в каждой строке, а сам файл поместить либо в каталог установки, либо в подкаталог стандартной библиотеки. В результате все перечисленные в файле и при этом существующие каталоги будут добавлены в путь поиска модулей в порядке очередности, что можно будет увидеть в списке переменной: в первом случае каталоги будут добавлены после каталога установки, но перед подкаталогом стандартной библиотеки, а во втором – после подкаталога.
а) б) __package__.py в) __main__.py г) __init__.py Показать решение.
Варианты ответов: создать папку с любым именем и поместить в неё файлы модулей, создать папку с файлом и поместить в неё файлы модулей, создать папку с файлом и поместить в неё файлы модулей, создать папку с файлом и поместить в неё файлы модулей.
16.8. module package
С помощью какой инструкции можно импортировать модуль из пакета?
16.9. foo spam
Укажите верный вариант импортирования относительно пакета модуля, находящегося в том же пакете, что и текущий модуль?
16.10. spam spam_2 foo spam spam_2
Пусть в некотором пакете расположены подпакеты и. Укажите верный вариант импортирования относительно пакета модуля, находящегося в каталоге, если текущий модуль расположен в каталоге.
16.11. module from module import *
Как предотвратить импортирование некоторых имен из модуля инструкцией?
а) from module import * б) from module import * __all__ в) from module import * __all__ __init__.py г) Пайтоне Показать решение.
Варианты ответов: начинать имена переменных, запрещенных к импорту инструкцией, символом нижнего подчеркивания, указать имена, разрешенные к импорту инструкцией, в списке на верхнем уровне модуля, указать имена, разрешенные к импорту инструкцией, в списке на верхнем уровне файла инициализации пакета, запрет на импорт имен данной инструкцией в не предусмотрен.
Ответ. а) from module import * б) from module import * __all__
начинать имена переменных, запрещенных к импорту инструкцией, символом нижнего подчеркивания, указать имена, разрешенные к импорту инструкцией, в списке на верхнем уровне модуля.
16.12. module
Укажите верные варианты перезагрузки ранее импортированного модуля.
reload importlib from importlib import reload
Функция находится в модуле стандартной библиотеки и может быть из него импортирована, например, инструкцией.
import_module(name, package=None)
Функция принимает путь к файлу импортируемого модуля в виде строки, в то время как в коде указан просто идентификатор!
Тесты на обработку исключений
17.2. else try/except/else/finally
В каком случае выполняется код блока составной инструкции?
else try
Необязательный блок выполняется только в случае отсутствия исключений в блоке.
17.3. finally try/except/else/finally
В каком случае выполняется код блока составной инструкции?
finally else
Блок выполняется в любом случае, независимо от того, было ли исключение или нет, и был ли блок или нет. Это полезно для завершения каких-то действий, которые нужно сделать в конце, например, закрыть файл или освободить ресурсы.
else except try/else try/else/finally
Блок может использоваться только при наличии хотя бы одного блока, следовательно варианты и недопустимы.
NameError except finally pass
Интерпретатор перехватит исключение, поэтому сработает блок. Блок срабатывает всегда, но в нем была использована лишь инструкция.
17.6. Питоне
Имеется ли в возможность вызывать исключения принудительно?
Python raise Exception
Для явного возбуждения исключений в предназначена инструкция, которой необходимо через пробел передавать имя класса или экземпляра возбуждаемого исключения. Данная инструкция может использоваться для явного возбуждения не только встроенных исключений, но и созданных пользователем. Пользовательские исключения представляют собой самые обычные классы, наследуемые от классов встроенных исключений, чаще всего от класса.
ZeroDivisionError except else
Интерпретатор перехватит принудительно возбужденное исключение, поэтому сработает блок, а не блок.
Альтернативы CPython
CPython является стандартной реализацией, но существуют и другие реализации, созданные для специфических целей и задач.
Jython
Основная цель данный реализации — тесная интеграция с языком Java. Работает следующим образом:
- Java-классы выполняют компиляцию программного кода на языке Python в байт-код Java.
- Полученный байт-код запускается на виртуальной машине Java (JVM).
Jython позволить Python-программам управлять Java-приложениями. Во время выполнения такая программа ведет себя точно так же, как настоящая программа на языке Java.
IronPython
Предназначена для обеспечения интеграции Python-программ с C# приложениями на Microsoft.NET Framework или Mono. Принцип работы такой же, как и у Jython.
PyPy
PyPy — это интерпретатор Python, написанный на Python (если быть точнее, то на RPython).
Особенностью PyPy является использование трассирующего JIT-компилятора (just-in-time), который на лету транслирует некоторые элементы в машинный код. Благодаря этому, при выполнении некоторых операций PyPy обгоняет CPython в несколько раз. Но плата за такую производительность — более высокое потребление памяти.
Часто задаваемые вопросы о трансляции Python-кода
Вопрос: Что такое CPython?
Ответ: CPython — эталонная реализация интерпретатора Python, написанная на C, которая транслирует код в байт-код, а затем исполняет его.
Вопрос: В чем разница между компиляцией и интерпретацией в Python?
Ответ: Python сначала компилирует исходный код в байт-код, а затем интерпретирует его с помощью виртуальной машины.
Вопрос: Что такое байт-код Python?
Ответ: Байт-код — это низкоуровневое представление кода Python, которое исполняется виртуальной машиной CPython.
Вопрос: Как PyPy ускоряет выполнение Python?
Ответ: PyPy использует JIT-компиляцию, которая транслирует часто исполняемый байт-код в машинный код на лету.
Вопрос: Можно ли превратить Python-программу в исполняемый.exe файл?
Ответ: Да, с помощью инструментов вроде PyInstaller или Nuitka, которые упаковывают интерпретатор и код в один файл.
Вопрос: Что такое виртуальная машина Python?
Ответ: Это среда выполнения, которая читает и исполняет байт-код, управляя памятью и вызовами функций.
Вопрос: Влияет ли GIL на производительность Python?
Ответ: GIL (Global Interpreter Lock) ограничивает выполнение только одного потока в один момент, что может снижать производительность в многопоточных задачах.
Вопрос: Что такое Jython?
Ответ: Jython — реализация Python на Java, которая компилирует код в байт-код Java для работы на JVM.
Вопрос: Как IronPython связан с.NET?
Ответ: IronPython транслирует Python-код в байт-код.NET (CIL), что позволяет использовать библиотеки.NET.
Вопрос: Почему Python считается медленным языком?
Ответ: Из-за динамической типизации и интерпретации байт-кода, что требует дополнительных проверок во время выполнения.





















