Коллекция вопросов (to keep your mind sharp) ========== From habra ---- (origin: http://habrahabr.ru/qa/5269/) * В чем отличие новых и старых классов? * Почему все просто не перешли на новые и не забыли о старых? * С какой версии старые классы не поддерживаются? * В чем отличие (i for i in arr) от [i for i in arr]? Проектирование, потоки: * Что такое гринлеты, Twisted, Tornado, в чём отличие мультипроцессинга от потоков, в чём их отличия в модулях Python(тест пройден если человек скажет что GIL работает в обоих случаях, а сами модули имеют одинаковый набор функций). * Про проектирование достаточно сложно говорить. Придумать простейший Singleton и объяснить какие альтернативы этому решению есть. Скажет что-то про мета-классы, про то, что сами по себе модули являются синглтоном — тест пройден. * Спроси что такое кольцевые зависимости. Дай пример кода с такой проблемой и попроси решить её или аргументировать почему выхода нет. Тест пройден если человек переместит все run-time используемые импорты в конец файла или перепроектирует систему, предложив вариант без кольцевых зависимостей. * Спроси про то, как работает with, будет ли он работать с со всеми переменными. Если нет(а так и есть), то почему и что нужно сделать. * Спроси про работу с юникодом. Лучше всего стимулировать на набор знаний о нём дав ошибку, которую можно найти в презентации farmdev.com/talks/unicode/, мне просто лень копипастить. * Задай простейшие задачи(фазз-базз, найти самый длинный лист в листе, реализовать пару простеньких алгоритмов, не забыв дать доступ в интернет). Всё это нужно чтобы посмотреть на решения, на код. Раньше хороший программист являлся базой данных алгоритмов, сейчас есть знания, требования и важнее, поэтому интернет дайте, разрешите найти суть алгоритма(конечно, вы же не собираетесь чтобы кодеры кодили без документации, книг, интернета?). * Еще можно про декораторы с параметрами спросить. Меня вот на одном собеседовании просили написать бесконечное генераторное выражение. (origin: http://pyobject.ru/blog/2010/02/04/python-quiz/) Типы данных, основные конструкции ---------- Как получить список всех атрибутов объекта Как получить список всех публичных атрибутов объекта Как получить список методов объекта В какой "магической" переменной хранится содержимое 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_. >>> 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 >>> y = Reg() >>> y >>> z = Reg() >>> for i in Reg: ... print i Написать юнит-тесты, за основу брать тесты выше, но не ограничиваясь ими. Метаклассы и дескрипторы ---------- Вопросы: Для чего используются, какие аргументы получают, что должны возвращать: методы __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.