Junior Python School
706 subscribers
92 photos
29 links
Surprising the python community with pure python 🔝

Moving channel from Russian to English.


Enthusiastic reviews can be written to @pythonjuniorschoolacc ❤️
Download Telegram
Итак. Ты уже дружишь с питоном, тебе понравилось и пришла пора искать работу.
У меня собралось много вопросов с разных собеседований меня и моих знакомых на позицию trainee/junior python dev.
Начнем с начала

Вопросы по Python для питонистов-джуниоров
1️⃣ Базовые вопросы
Какие существуют типы данных в python 3?
Какие из них изменяемые, а какие нет?
Можно ли создать множество состоящее из других множеств?
Что нужно сделать с классом, чтобы он мог стать ключом словаря?
Как работает scope в python?
2️⃣ Вопросы о вашей мотивации в python
Почему Вы выбрали python?
В чем достоинства и недостатки python как языка общего назначения?
Для каких задач используется python?
Пробовали ли Вы python 2?
Отличие python 3 и python 2.
Что нового появилось в python 3.7?
Смотрели ли вы на python 3.8?
Дзен python помните?
3️⃣ Стандартная библиотека
Какие модули стандартной библиотеки вы использовали?
Что вы знаете про модули collections, pickle?
Как работает идея абстрактных классов в python?
4️⃣ Основные вопросы python
*args, **kwargs в python?
Можно ли в python сделать бесконечную рекурсию?
Анонимные функции в python
Итератор и генератор.
Генератор выражений
Магические методы.
Магические методы __new__ и __init__
Как работает __slots
__?
Структура Exceptions в python 3.
Как под капотом реализован список и словарь в python.
Built-in functions в python.
Что значит, что объект сallable.
Что такое декоратор?
Встроенные декораторы
staticmethod, classmethod - в чем разница?
Может ли classmethod быть абстрактным в терминах python 3?
Менеджеры контекста
Как в питоне реализованы public, private и protected methods?
Как импортировать приватный метод из стороннего модуля?
Классы нового стиля в python.
5️⃣ Продвинутый python
Python сразу интерпретируется интерпретатором или есть промежуточный шаг?
Диамантовая проблема в python.
MRO в python 3.
Декораторы с параметрами
Написать менеджер контекста через класс и через функцию.
Дескрипторы
Метаклассы

Удачи! Тут еще нет, как минимум, большей части вопросов про ООП, шаблонам проектирования, web разработке, тестированию, многопоточности, devops, гиту, frontendу, python фреймворкам, базам данных и другим важным темам, но список уже получился большим.
Продолжение следует...)
Проекты написанные на django
Python interning
Shared objects - ranges и специфические объекты неизменяемого типа которые CPython инстанцирует и загружает в память каждый раз при запуске интерпретатора
Более того, python умеет интернировать(кешировать ASCII символы, цифры или _ в памяти во время создания новой строки) строки меньше 20 символов
Это все помогает оптимизировать работу python.

Отсюда вывод:
Python что-то ускоряет, когда может:
Пример 1
>> a = 'ee'
>> a[0] is a[1]
True

>> a='x'
>> b='x'
>> a is b
True

Пример 2
>> a = 'ΩΩ'
>> a[0] is a[1]
False

>> a='Ω'
>> b='Ω'
>> a is b
False

Обычно python умеет делать много чего неявно, но его можно заставить...
>> a = 'I hate frontend'
>> b = 'I hate frontend'
>> a is b
False

>> import sys
>> c = sys.intern('I hate frontend')
>> d = sys.intern('I hate frontend')
>> c is d
True
>> c is a
False

Самый простой способ узнать про неявное интернирование - проверить id объекта.
>> s='*'
>> for i in range(2):
.. s+='*'
.. print(id(s), s)
140277841241232 **
140277841241232 ***
Хочу обсудить питонячье понимание модификаторов доступа.
Модификаторы доступа помогают разделить методы и переменные на не предназначенные для внешнего использования, не рекомендуемые для использования из вне и предназначенные только для использования внутри.
Для этого используются нижние подчеркивания перед именем.
class Underscore:

def method():
return 'public method'

def _method(): # одно _ работает на уровне соглашения — означает, что лучше такую переменную не трогать из вне
return 'It is better not to use this method outside'

def __method(): # два __ - питон не даст явно вызвать такой метод из вне(AttributeError)
return 'private method'
Это была простая часть. Очень известная. Но есть более продвинутые штуки.
Переменная с даже одним _ - не импортируется звездочкой
from module import *
Стандартно будут импортироваться только public methods.
Чтобы получить доступ к переменной с нижнем подчеркиванием нужно явно указать ее при импорте, или внести в список __all__ импортируемого модуля.
from module import _var
*Кстати, питонисты используют нижнее подчеркивание в конце имени, чтобы избежать конфликтов имен. Про это читай в PEP8

В питоне, если очень хочется, то можно сделать все. (Ну почти)
Даже достучаться к приватному методу)) Это называется name mangling - искажение имен.
На самом деле питон просто сохраняет имена начинающиеся с двух подчеркиваний немного иначе
class Magic:
def __private(self):
return 'I am private AF'
Попробуем вызвать метод
magic = Magic()
magic.__private()
Получим ожидаемое:
AttributeError: 'Magic' object has no attribute '__private'
На самом деле питон создал этот метод, но с именем _Magic__private, то есть долепил имя класса в имя, чтобы нельзя было переопределить метод точно так же в потомке
Проверим
magic.__Magic__private()
'I am private AF'
Питон искажает имена всех переменных, которые начинаются с двойного подчеркивания. Вот такой вот хак.
Задачка
Почему это работает?

_MagicUnderscore__secret = 'Эта дичь сработает?'


class MagicUnderscore:

def magic(self):
return __secret


print(MagicUnderscore().magic())
Вернет
Эта дичь сработает?

Подумай, почему оно так работает?
Сегодня решил поговорить про lambda functions в python.
lambda функция - анонимная функция(у которой нет имени)
Как мы знаем, в питоне все - объекты. Даже функции. А если объект может существовать без имени, то и функция может просто можно работать с функцией как с объектом.

Простой пример
def hello(me, name):
return f'Hello from {me}, {name}!'
Ничто иное как
hello = lambda me, name: f'Hello from {me}, {name}!'
В общем, ничего сложного - просто функции одного выражения. Кратко и удобно, можно сразу отправлять такую lambda, как аргумент в функцию.
Так и часто и используют, как аргументы функций. Простой пример:
sorted(range(-5, 6), key=lambda x: x * x)
Но все же чаще функции побольше, их удобнее читать в стандартном формате.
Сначала все просто, as always.
Но у питона свои особенности, как всегда и их стоит учитывать.
Lambda функции в питоне живут в nonlocal пространстве и умеют запоминать свой контекст.
Пример
def hello(me):
return lambda name: f'Hello from {me}, {name}!'
greeting = hello('Jack')
greeting('Kate')
Вернет
'Hello from Jack, Kate!'
То есть lambda помнит переменные своего подпространства (me), связана с ними и может их использовать.
Важно не использовать lambda функции просто так.
Я видел код вида
class Hello:
greet = lambda self: print('Hello')
Это может показаться короче, но читать и поддерживать такой код сильно сложнее, к сожалению.
После простой теории надо давать убийственные примеры, а то скучно.


names = ['Jack', 'Michael', 'Kate', 'Jimmy', 'Python']


def greetings():
return [lambda me: f'Hello from {me}, {name}!' for name in names]


for greeting in greetings():
print(greeting('Creator'))

Вернет
Hello from Creator, Python!
Hello from Creator, Python!
Hello from Creator, Python!
Hello from Creator, Python!
Hello from Creator, Python!
Подумай, почему оно так работает?
Если в python3
s = 'f(φ)==f(φ)'
то
s[1] is s[7], s[2] is s[8]

Вернет
Что выведет запрос?

Вариант 1 - 2
👍👍👍 11%
Вариант 2 - 6
👍👍👍👍👍👍👍👍 32%
Вариант 3 - 4
👍👍👍👍👍👍 21%
Вариант 4 - 1
👍👍 5%
А где python? - 6
👍👍👍👍👍👍👍👍 32%
👥 19 человек уже проголосовало.
Channel name was changed to «Junior Python School»
Если у вас есть знакомые питонисты - киньте им этот тест, запутаться в этом может каждый.



fromkeys - позволяет из последовательности и значения сделать словарь с элементами последовательности с данным значением
>>> dict.fromkeys(['python', 'sql', 'c++'], 'good')

{'python': 'good', 'sql': 'good', 'c++': 'good'}



Или setdefault - если ключ в словаре не найден - то создаст этот ключ с заданным значением по умолчанию и вернет его.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.setdefault('js', 'bad')

'oh no'

>>> d.setdefault('php', 'bad')

'bad'



Или get - позволяет получить значение из словаря по ключу или какое-то значение по умолчанию, если ключ не найден.
Пользуюсь этим методом постоянно.
Часто удобнее, чем просто стучаться к элементу через квадратные скобочки ибо не выкидывает исключение KeyError, если ключа не найдено.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.get('js', 'no such key')

'oh no'

>>> d.get('php', 'no such key')

'no such key'

>>> d['php']

Traceback (most recent call last):
 File "<input>", line 1, in <module>
KeyError: 'php'



Интересное происходит с popitem - этот метод возвращает случайную пару ключ-значение из словаря и удаляет его их словаря.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.popitem()

('sql', 'good')

>>> d

{'python': 'cool', 'js': 'oh no'}



С pop похожая ситуация - этот метод удаляет заданное значение из словаря и возвращает значение удаленного элемента. При этом у метода есть тоже параметр по умолчанию, он возвращается если ключа не найдено. Если пара не найдена - кидается наше любимое исключение KeyError
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.pop('php', 'no such value')

'no such value'

>>> d.pop('js')

'oh no'

>>> d.pop('php')

Traceback (most recent call last):
 File "<input>", line 1, in <module>
KeyError: 'php'



Про keys, values и items - особо говорить не нужно. Нужны чаще всего для итерации по словарю. Нужно только обратить внимание, что возвращаются объекты типов dict_keys, dict_values и dict_items
>>> d = {'python': 'cool', 'sql': 'good'}

>>> d.keys()

dict_keys(['python', 'sql'])

>>> d.values()

dict_values(['cool', 'good'])

>>> d.items()

dict_items([('python', 'cool'), ('sql', 'good')])



Посмотрим на вообще все публичные методы
(которые не начинаются с нижнего подчеркивания)
>>> [attr for attr in dir(dict()) if attr[0]!='_']

>>> ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']



Мы не рассмотрели еще методы copy, clear и update.
C ними все не сложно:
copy - создает shallow копию данного словаря,
clean - удаляет все ключи и значения из словаря и оставляет его пустым,
update - обновляет словарь значениями из другого словаря.
>>> d1 = {1:1 , 2:3}
>>> d2 = {3:3 , 2:2}
>>> d1.update(d2)
>>> d1
{1: 1, 2: 2, 3: 3}



Лайфхак для пользователей python 3.5+
update можно заменить вот так:
{**d1, **d2}
{1: 1, 2: 2, 3: 3}
Пришло время обсудить вот этот тест.

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


Запустим в интерпретаторе:
>>> isinstance((), tuple)
True
>>> isinstance((1), tuple)
False
>>> isinstance((1, 2), tuple)
True

Все, можно спокойно выбрать правильный ответ))😜

Но почему так?
Что мы на самом деле делаем:
Мы проверяем является ли какое-то значение объектом класса кортеж.

Значение () - это способ объявления пустого кортежа

Значение (1) - это просто 1 в скобочках
>>> type((1))
<class 'int'>
Для того, чтобы сделать это значение кортежем нужно просто добавить запятую: (1,)
>>> type((1,))
<class 'tuple'>

Ну а (1, 2) - это простой кортеж из двух элементов.

Лайфхак:
Функция tuple() - позволяет сделать из любой последовательности кортеж.

Пример:
>>> tuple('join us')
('j', 'o', 'i', 'n', ' ', 'u', 's')
>>> tuple(['Поделись', 'каналом', 'c', 'друзьями'])
('Поделись', 'каналом', 'c', 'друзьями')
Наша команда создала тест

Просто 9 вопросов по python. В конце можно получить сертификат о прохождении - мелочь, а приятно)
Немного поменяли способ подсчета баллов теста выше.
Все результаты пересчитаны, чтобы стало проще
Интересно увидеть статистику по всем пользователям?
Anonymous Poll
50%
Покажите графики
19%
Покажите лучших
31%
Ещё тестов создайте
Статистика по тесту 📊.

Пока что его прошло 77 человек. Особенно радует, что многие проходили его несколько раз с одного ip, чтобы получить заветную пятерку!


Наша команда уже готовит следующий тест - не пропусти.


У нас есть план запустить бесплатный интенсив, без какой-либо жуткой рекламы, по модулю itertools.

Покажем базовые возможности, а также красивые и удобные фишки библиотеки.

Если интересно поучаствовать - напиши об этом нашему боту, хотим знать сколько тут замотивированных на учебу!




Поделись каналом с друзьями - мы сейчас только начинаем развиваться, и без твоей помощи ничего грандиозного не получится)

Твоя обратная связь мотивирует команду Junior Python School работать лучше и быстрее, пользуйся этим)

Участвуй в нашем конкурсе. Шансы выиграть что-то сейчас очень высоки!