Написать пост

Еще 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-строк с подстановками.

Заключение

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

Следите за новыми постами
Следите за новыми постами по любимым темам
68К открытий69К показов