Вопросы и задания по Python ∞
Меня периодически спрашивают о тестовых заданиях по Python-тематике. Я решил обобщить вопросы и написать их в одном месте. Я не использую эти вопросы и задания в собеседованиях, но использую при обучении.
Типы данных, основные конструкции
- Как получить список всех атрибутов объекта
- Как получить список всех публичных атрибутов объекта
- Как получить список методов объекта
- В какой "магической" переменной хранится содержимое help?
- Есть два кортежа, получить третий как конкатенацию первых двух
- Есть два кортежа, получить третий как объединение уникальных элементов первых двух кортежей
- Почему если в цикле меняется список, то используется
for x in lst[:], что означает[:]? - Есть два списка одинаковой длины, в одном ключи, в другом значения. Составить словарь.
- Есть два списка разной длины, в одном ключи, в другом значения. Составить словарь. Для ключей, для которых нет значений использовать None в качестве значения. Значения, для которых нет ключей игнорировать.
- Есть словарь. Инвертировать его. Т.е. пары ключ: значение поменять местами — значение: ключ.
- Есть строка в юникоде, получить 8-битную строку в кодировке utf-8 и cp1251
- Есть строка в кодировке cp1251, получить юникодную строку
Функции
Написать функцию, которой можно передавать аргументы либо списком/кортежем, либо по одному. Функция производит суммирование всех аргументов.
>>> f(1, 2, 3) 6 >>> f([1, 2, 3]) 6 >>> f((3, 5, 6)) 14 >>> f(3, (5, 6)) 14
Написать функцию-фабрику, которая будет возвращать функцию сложения с аргументом.
>>> add5 = addition(5) # функция addition возвращает функцию сложения с 5 >>> add5(3) # вернет 3 + 5 = 8 8 >>> add5(8) # вернет 8 + 5 = 13 13 >>> add8 = addition(8) >>> add8(2) # вернет 2 + 8 = 10 10 >>> add8(4) # вернет 4 + 8 = 12 12
Написать варианты с обычной "внутренней" и анонимной lambda-функцией.
Написать фабрику, аналогичную п.2, но возвращающей список таких функций
>>> additionals = addition_range(0, 5) # список из функций сложения от 0 до 5 включительно
т.е. аналогичное
[add0, add1, add2, add3, add4, add5]Написать аналог map:
- первым аргументом идет либо функция, либо список функций
- вторым аргументом — список аргументов, которые будут переданы функциям
- полагается, что эти функции — функции одного аргумента
>>> mymap([add0, add1, add2], [1, 2, 3]) [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
в данном случае "развернутая" запись будет:
[(add0(1), add0(2), add0(3)), (add1(1), add1(2), add1(3)), (add2(1), add2(2), add2(3))]
Итераторы
Написать функцию-генератор cycle которая бы возвращала циклический итератор.
>>> i = iter([1, 2, 3]) >>> c = cycle(i) >>> c.next() 1 >>> c.next() 2 >>> c.next() 3 >>> c.next() 1
Написать функцию-генератор chain, которая последовательно итерирует переданные объекты (произвольное количество)
>>> i1 = iter([1, 2, 3]) >>> i2 = iter([4, 5]) >>> c = chain(i1, i2) >>> c.next() 1 >>> c.next() 2 >>> c.next() 3 >>> c.next() 4 >>> c.next() 5 >>> c.next() Traceback (most recent call last): ... StopIteration
Для функций и итераторов написать доктесты
Модули
- У нас есть импортированный модуль foo, как узнать физический путь файла, откуда он импортирован?
- Из модуля foo вы импортируете модуль feedparser. Версия X feedparser'а есть в общесистемном каталоге site-packages, версия Y — рядом с модулем foo. Определена переменная окружения
PYTHONPATH, и там тоже есть feedparser, версии Z. Какая версия будет использоваться? - Как посмотреть список каталогов, в которых Python ищет модули?
- У вас есть модуль foo, внутри него импортируется модуль bar. Рядом с модулем foo есть файлы
bar.pyиbar/__init__.pyКакой модуль будет использоваться. - Что означает и для чего используется конструкция
__name__ == '__main__'
Классы
Написать базовый класс Observable, который бы позволял наследникам:
- при передаче
**kwargsзаносить соответствующие значения как атрибуты - сделать так, чтобы при print отображались все публичные атрибуты
>>> class X(Observable): ... pass >>> x = X(foo=1, bar=5, _bazz=12, name='Amok', props=('One', 'two')) >>> print x X(bar=5, foo=1, name='Amok', props=('One', 'two')) >>> x.foo 1 >>> x.name 'Amok' >>> x._bazz 12- при передаче
Написать класс, который бы по всем внешним признакам был бы словарем, но позволял обращаться к ключам как к атрибутам.
>>> x = DictAttr([('one', 1), ('two', 2), ('three', 3)]) >>> x { 'one': 1, 'three': 3, 'two': 2} >>> x['three'] 3 >>> x.get('one') 1 >>> x.get('five', 'missing') 'missing' >>> x.one 1 >>> x.five Traceback (most recent call last): ... AttributeErrorПункт 2 с усложнением: написать родительский класс
XDictAttrтак, чтобы у наследника динамически определялся ключ по наличию методаget_<KEY>.>>> class X(XDictAttr): ... def get_foo(self): ... return 5 ... def get_bar(self): ... return 12 >>> x = X({'one': 1, 'two': 2, 'three': 3}) >>> x X: { 'one': 1, 'three': 3, 'two': 2} >>> x['one'] 1 >>> x.three 3 >>> x.bar 12 >>> x['foo'] 5 >>> x.get('foo', 'missing') 5 >>> x.get('bzz', 'missing') 'missing'Написать класс, который регистрирует свои экземпляры и предоставляет интерфейс итератора по ним
>>> x = Reg() >>> x <Reg instance at 0x98b6ecc> >>> y = Reg() >>> y <Reg instance at 0x98b6fec> >>> z = Reg() <Reg instance at 0x98ba02c> >>> for i in Reg: ... print i <Reg instance at 0x98b6ecc> <Reg instance at 0x98b6fec> <Reg instance at 0x98ba02c>
Написать юнит-тесты, за основу брать тесты выше, но не ограничиваясь ими.
Метаклассы и дескрипторы
Вопросы:
- Для чего используются, какие аргументы получают, что должны возвращать: методы
__new__и__init__классов - Какие аргументы получает
__new__и__init__у метакласса?
Задания:
Реализовать дескрипторы, которые бы фиксировали тип атрибута
>>> class Image(object): ... height = Property(0) ... width = Property(0) ... path = Property('/tmp/') ... size = Property(0) >>> img = Image() >>> img.height = 340 >>> img.height 340 >>> img.path = '/tmp/x00.jpeg' >>> img.path '/tmp/x00.jpeg' >>> img.path = 320 Traceback (most recent call last): ... TypeErrorРеализовать базовый класс (используя метакласс), который бы фиксировал тип атрибута
>>> class Image(Object): ... height = 0 ... width = 0 ... path = '/tmp' ... size = 0 >>> img = Image() >>> img.height = 340 >>> img.height 340 >>> img.path = '/tmp/x00.jpeg' >>> img.path '/tmp/x00.jpeg' >>> img.path = 320 Traceback (most recent call last): ... TypeError
Реализовать базовый класс (используя метакласс) и дескрипторы, которые бы на основе класса создавали SQL-схему (ANSI SQL) для модели:
>>> class Image(Table): ... height = Integer() ... width = Integer() ... path = Str(128) >>> print Image.sql() CREATE TABLE image ( height integer, width integer, path varchar(128) )реализовывать
[NOT] NULL,PRIMARY KEY,FOREIGN KEY,CONSTRAINTSне нужно. Достаточно реализации двух типов:IntegerиStr.
