Еще 10 фишек Python, которые помогут новичку выделиться

Аватарка пользователя Елена Капаца

Собрали еще тележку фишек из нескольких версий Python, чтобы вы могли выделиться на стажировке.

Midjourney так хорошо справляется с рисунками девушек и питонов… Сразу вспоминается правило 34: “В интернете существует порно на любую тему. Без исключений”.

В Python никогда не бывает излишка полезных приемов. Чем больше таких вы изучите, тем выше вероятность, что сможете оперативно справиться с какой-либо трудностью на практике. Или покажете себя с лучшей стороны на техническом собеседовании. В этой статье я расскажу о хитростях, которые могут помочь новичкам (и не только) в развитии навыка. Я собрала тележку фишек и все еще нахожу новые – и порционно делюсь ими с вами.

Предыдущие статьи цикла:

Проверка наличия элемента в множестве

Мы можем проверить, находится ли тот или иной элемент в списке с помощью оператора in:

			large_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

if 5 in large_list:
    print("5 найден в списке.")
else:
    print("5 не найден в списке.")
		

То же применимо и для множеств (set):

			large_set = set(large_list)

if 5 in large_set:
    print("5 найден в множестве.")
else:
    print("5 не найден в множестве.")
		

Автоматическое добавление ключа словарю

Если создать словарь средствами collections.defaultdict, добавить хотя бы один элемент, а затем обратиться к несуществующему ключу:

			>>> from collections import defaultdict
>>> 
>>> my_dict = defaultdict(int)
>>> 
>>> my_dict['apple'] = 3
>>> my_dict ['banana' ] = 2
>>> print(my_dict['orange'])
>>> print(my_dict)
		

то интерпретатор самостоятельно добавит новый элемент:

			... 0
... defaultdict(, {'apple': 3, 'banana': 2, 'orange': 0})
		

try / except + else + finally

Мастхэв для начинающих питонистов — пара try / except, обработчик исключений. Шикарным дополнением к такому блоку является, на мой взгляд, else: он опишет поведение программы на случай других ошибок, которых может быть немало!

Более того, добавив finally, вы выполните завершающие работы, например, скомандуете выслать уведомление:

			>>> try:
>>>     result = 10 / 2
>>> except ZeroDivisionError:
>>>     print( "Ошибка: деление на ноль невозможно.")
>>> else:
>>>     print("Результат:", result)
>>> finally:
>>>     print( "Программа выполнена.")
... Результат: 5.0
... Программа выполнена.
		

Проверка существования переменной с помощью «моржового» оператора

Если мы объявили две переменные, но не задали любой из них значение, то с помощью оператора := (Walrus Operator) можно спасти программу от падения и добавить обрабатывающую логику. В первом случае, в переменные name1, name2 мы ничего не записали, значит, программа зайдет в блок else:

			>>> if __name__ == '__main__':
>>>     name1, name2 = '', ''
>>> 
>>>     if name := name1 or name2:
>>>         print(name1)
>>>         print('Успешно!')
>>>     else:
>>>         print('Имя не найдено...')... Имя не найдено...
		

Во втором случае заполнена только одна из переменных, но программа отработает без ошибки:

			>>> if __name__ == '__main__':
>>>     name1, name2 = 'Сергей', ''
>>> 
>>>     if name := name1 or name2:
>>>         print(name1)
>>>         print('Успешно!')
>>>     else:
>>>         print('Имя не найдено...')
... Сергей
... Успешно!
		

Оператор match для проверки типа

Теперь освоение новых библиотек у вас точно ускорится.

Порой, трудно понять, какой тип данных возвращает функция или метод. В таких случаях помогают match и встроенные функции приведения к тому или иному типу данных:

			>>> var = 1
>>> 
>>> match var:
>>>     case str():
>>>         print('Строковый тип')
>>>     case bool():
>>>         print('Булевый тип')
>>>     case float():
>>>         print('Число с плавающей запятой')
>>>     case int():
>>>         print('Целочисленный тип')
>>>     case list():
>>>         print('Список')
>>>     case None:
>>>         print("None")
>>>     case _:
>>>         print('Другой тип данных')... Целочисленный тип
		

Встроенные функции попытаются привести к своему значению переменную. Но если положить в var единицу, как примере выше, то мы минуем float().

Чтобы программа не упала, стоит заложить дальнейшую обработку var только в подходящие функции-наследнице кейсы.

Включение генераторов, сетов

В предыдущей статье с фишками я рассказывала, что есть эффективный способ генерировать списки — «списковое включение» (List Comprehension):

			>>> names = [
>>>     'Данил',
>>>     'Михаил',
>>>     'Оля']
>>> [x for x in names if"a"in x]] # Выберет имена, где есть "а"... ['Данил', 'Михаил']
		

Оказывается, этому поддаются и другие составные типы — генераторы и сеты.

			>>> s = {s*2 for s in range(10)} # Перемножит числа 1-10 на два
>>> print(s)
... {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
		

Pretty Print словаря

Выводить многоуровневые словари с print() — боль: разрывы строк исчезнут, файл станет нечитаемым:

			>>> my_d: dict = {
>>>     "data": {
>>>         "TICKET_ID": "64278401",
>>>         "livechatStatus": {
>>>             "enabled": False
>>>         },
>>>         "requestHeaders": {
>>>             "x-forwarded-host": [
>>>                 "bot.jaicp.com:443"
>>>             ],
>>>             "x-forwarded-server": [
>>>                 "bot.jaicp.com"
>>>             ],
>>>             "x-forwarded-for": [
>>>                 "80.93.184.190"
>>>             ],
>>>             "host": [
>>>                 "zfl-chatadapter-direct-upstream"
>>>             ],
>>>             "content-length": [
>>>                 "978"
>>>             ],
>>>             "accept": [
>>>                 "*/*"
>>>             ],
>>>             "content-type": [
>>>                 "application/json"
>>>             ]
>>>         }
>>>     }
>>> }
>>> print(my_d)
... {'data': {'TICKET_ID': '64278401', 'livechatStatus': {'enabled': False}, 'requestHeaders': {'x-forwarded-host': ['bot.jaicp.com:443'], 'x-forwarded-server': ['bot.jaicp.com'], 'x-forwarded-for': ['80.93.184.190'], 'host': ['zfl-chatadapter-direct-upstream'], 'content-length': ['978'], 'accept': ['*/*'], 'content-type': ['application/json']}}}
		

Но встроенная утилита pprint, выдаст в командной строке «причёсанный» словарь:

			>>> from pprint import pprint
>>> pprint(my_d)
... {'data': {'TICKET_ID': '64278401',
...           'livechatStatus': {'enabled': False},
...           'requestHeaders': {'accept': ['*/*'],
...                         'content-length': ['978'],
...                         'content-type': ['application/json'],
...                         'host': ['zfl-chatadapter-direct-upstream'],
...                         'x-forwarded-for': ['80.93.184.190'],
...                         'x-forwarded-host': ['bot.jaicp.com:443'],
...                         'x-forwarded-server': ['bot.jaicp.com']}}}
		

TypeVarTuple

Допустим, мы создаём функцию convert_first_int(), которая возвращает кортеж практически неизменным, только первый элемент приводит к целочисленному типу:

			>>> from typing import TypeVarTuple
>>> 
>>> Ts = TypeVarTuple("Ts")
>>> 
>>> def convert_first_int(values: tuple[int|str|float, *Ts]) -> tuple[int, *Ts]:
>>>     return (int(values[0]), *values[1:])
>>> 
>>> print(repr(convert_first_int(("1", "2", "3"))))
... (1, '2', '3')
		

TypeVarTuple представляет собой произвольный кортеж потенциально разных типов. Полезно, если функция имеет дело только с первым элементом кортежа, и нам «разрешит» любые оставшиеся типы.

Импорт

В крайней версии Python 3.12 наконец стало возможным импортировать модули в адекватном для английского языка порядке слов!

			import LinearRegression from sklearn.linear_model
		

Защита от SQL-инъекций

Безопасники скажут вам, что: внутрь текста (например, в поле анкеты) можно внедрить SQL-запрос и даже дропнуть базу данных. Но не дай бог нам с вами увидеть такое на проде.

Еще 10 фишек Python, которые помогут новичку выделиться 1

Начиная с Python 3.11 мы можем использовать LiteralString во избежание таких уязвимостей:

			def caller(
    arbitrary_string: str,
    query_string: LiteralString,
    table_name: LiteralString,
) -> None:
    run_query("SELECT * FROM students")       # ok
    run_query(query_string)                   # ok
    run_query("SELECT * FROM " + table_name)  # ok
    run_query(arbitrary_string)               # type checker error
    run_query(                                # type checker error
        f"SELECT * FROM students WHERE name = {arbitrary_string}"
    )
		

Как видно из первой половины сниппета, arbitrary_string — это привычная строковая переменная. А вот query_string и table_name — уже «буквально строки», без возможных F-строк с подстановками.

Заключение

Некоторые приемы могут показаться непонятными в хайлайтах документации ЯП, и ясными становятся только после запуска примера. Поэтому не злитесь на себя, если такой код забывается. Просто сохраните статью в закладки, чтобы вернуться к описанным трюкам в один прекрасный день.

Python
67462