Важные концепции в Python, которые помогают программисту в работе

от автора

Привет, Хабр! Сегодня поговорим о Python и некоторых концепциях языка, которые пригодятся многим. Мы сделали подборку, которая в первую очередь будет полезна начинающим разработчикам, хотя, возможно, найдут в ней что-то и более опытные программисты. Самое интересное — под катом.

Мультипроцессинг в Python

Здесь речь идёт о встроенном модуле multiprocessing. Он позволяет запускать более одной функции одновременно. А это бывает весьма полезно.

import time import datetime   def yourfunction(x): start = datetime.datetime.now() time.sleep(1) end = datetime.datetime.now() return f'x={x} start at {start}, end at {end}'   if __name__ == '__main__': with multiprocessing.Pool(processes=3) as pool:     data = pool.map(yourfunction, [1, 2, 3, 4, 5, 6, 7])   for row in data:     print(row)

x=1 start at 2023-04-16 13:39:32.035510, end at 2023-04-16 13:39:33.037308
x=2 start at 2023-04-16 13:39:32.035795, end at 2023-04-16 13:39:33.037324
x=3 start at 2023-04-16 13:39:32.037349, end at 2023-04-16 13:39:33.037629
x=4 start at 2023-04-16 13:39:33.037725, end at 2023-04-16 13:39:34.040135
x=5 start at 2023-04-16 13:39:33.037892, end at 2023-04-16 13:39:34.040160
x=6 start at 2023-04-16 13:39:33.037986, end at 2023-04-16 13:39:34.040161
x=7 start at 2023-04-16 13:39:34.040454, end at 2023-04-16 13:39:35.045383

Что здесь происходит? Код выполняет одновременно три функции.

  1. yourfunction(1), yourfunction(2) и yourfunction(3) выполняются одновременно.

  2. yourfunction(4), yourfunction(5) и yourfunction(6) также выполняются одновременно.

  3. yourfunction(7) работает отдельно от других.

Кортежи (tuple) в Python. Обычная распаковка и распаковка кортежа с *

Кортежи (tuple) в Python — неизменяемые структуры данных. Ну а концепция распаковки может быть крайне полезна в ряде случаев.

person = ['bob', 30, 'male']   name, age, gender = person   # name='bob', age=30, gender='male'

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

fruits = ['apple', 'orange', 'pear', 'pineapple', 'durian', 'banana']   first, second, *others = fruits   # first='apple', second='orange' # others = ['pear', 'pineapple', 'durian', 'banana']

Тернарный оператор

Тернарный оператор — это оператор, который используется для демонстрации какого-то условия, то есть вместо условной конструкции. Вот как его можно использовать.

score = 57 if score > 90:   grade = 'A*' elif score > 50:   grade = 'pass' else:   grade = 'fail'   # grade = 'pass'

Обычный блок if-elif-else.

score = 57 grade = 'A*' if score > 90 else 'pass' if score > 50 else 'fail'   # grade = 'pass'

А ещё можно сжать блок if-elif-else в ОДНУ строку, используя тернарный оператор.

Генератор списка + понимание генератора словарей/множеств

А вот практическое применение этой концепции. Так, с генератором списка можно создавать собственный список в одной строке кода.

lis = [expression for i in iterable if condition]   l1 = [i for i in range(1,4)]          # [1,2,3]   l2 = [i*2 for i in range(1,4)]        # [2,4,6]   l3 = [i**2 for i in range(1,4)]       # [1,4,9]   l4 = [i for i in range(1,4) if i%2==1]# [1,3]

Также генератор множества и генератор словаря можно применять для создания множеств и словарей таким же образом, как и в случае создания списков, используя генератор списков.

set1 = {i for i in range(1,4)}      # {1,2,3}   d1 = {i:i**2 for i in range(1,4)}   # {1:1, 2:4, 3:9}

* *args и **kwargs

Ещё одна интересная возможность. Так, *args дают возможность функциям принимать любое количество позиционных аргументов. Они будут храниться в кортеже args.

def test(a, b, *args):   print(f'{a=} {b=} {args=}')   test(1,2,3,4,5)  # a=1 b=2 args=(3,4,5)

Ну а **kwargs позволяют функциям принимать любое количество аргументов ключевого слова (которые будут храниться в словаре kwargs).

def test(a, b, **kwargs):   print(f'{a=} {b=} {kwargs=}')   test(a=1, b=2, c=3, d=4)# a=1 b=2 kwargs={'c': 3, 'd': 4}

Одновременная работа с несколькими .py-файлами

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

# helper.py def test123():   print('test123 is called')   # main.py from helper import test123   test123()# test123 is called  

if __name__ == ‘__main__’

Ну а здесь речь идёт о том, что строка из заголовка оценивается как True в файле .py. Правда, лишь в том случае, если мы запускаем сам файл напрямую. Строка же используется для того, чтобы случайно не запустить строки кода, которые не планировалось использовать.

# helper.py def test123():   print('test123 is called')   if __name__ == '__main__':   # this line only runs if we run helper.py DIRECTLY   print('print statement from helper.py')   # main.py from helper import *   test123()# test123 is called

Библиотеки построения веб-API Python

В этом пункте — без кода. Речь о том, что библиотеки эти крайне полезны для разработчика на Python, причём некоторые узнают об их существовании достаточно поздно. Вот две простые для освоения даже начинающими программистами библиотеки на Python:

  • Python FastAPI — простое создание API.

  • Python Flask — создание API и простых веб-приложений при помощи Flask. 

Декораторы

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

def add_exclamation_mark(your_function):   def inner(*args, **kwargs): return your_function(*args, **kwargs)   return inner   @add_exclamation_mark def greet(name):   return f'hello {name}'

Зачем здесь нужен декоратор? Декораторы — функции, которые:

  • принимают другую функцию

  • настраивают работу функции

  • возвращают другую функцию

И когда @add_exclamation_mark ставится над функцией greet, мы меняем работу greet, декорируя её.

# @add_exclamation_mark # def greet(name) # # ^ THIS IS THE SAME AS BELOW: # # greet = add_exclamation_mark(greet)   print(greet('tim'))# hello tim!

Из-за декоратора функция greet ведет себя по-другому, и теперь у нее есть дополнительный ! после возвращаемого значения.

Генераторы + ключевое слово yield

Это слово похоже на return. Но за малым исключением — функция в этом случае не останавливается после чего-то. Функция с yield становится функцией-генератором и может иметь несколько выходных данных.

def simple_generator():   yield 'apple'   yield 'orange'   yield 'pear'   for fruit in simple_generator():   print(fruit)   # apple orange pear

Лямбда-функции

О них многие знают, но не все используют. На самом деле всё просто.

def add(x, y):   return x + y   # this is the same as   add = lambda x,y : x + y

Мы используем лямбда-функцию, когда нам ненадолго требуется безымянная функция. Вот пример:

def test():   return 'hello'   # this is the same as   test = lambda : 'hello' def test2(a,b,c,d):   return (a+b) / (c-d)   # this is the same as   test2 = lambda a,b,c,d : (a+b) / (c-d)

Лямбда-функции могут иметь любое количество аргументов, но у каждой может быть только одно выражение. Выражение вычисляется и возвращается. Эти функции могут быть использованы везде, где требуется объект-функция.

assert + raise + custom-исключения

И ещё одна полезная концепция. Здесь ключевое слово assert даёт возможность провести тест на работоспособность в середине кода. Если оценка >100, возникает ошибка AssertionError, после чего программа принудительно завершает работу.

assert score <= 100 # ensuring that score cannot be above 100.

Ключевое слово raise позволяет принудительно вызвать исключение (также можно настроить сообщение в исключении).

if score > 100:   raise Exception('score cannot be higher than 100') # ensuring that score cannot be above 100.

Ну и плюс можно создавать свои собственные типы Exception, наследуя от класса Exception.

class ScoreException(Exception):   def __init__(self): super().__init__('score cannot be higher than 100')   if score > 100:   raise ScoreException()

Конечно, в этой подборке указаны далеко не все фишки, которые используют как опытные, так и не очень разработчики практически каждый день. Если у вас есть такая фишка, расскажите о ней в комментариях — порадуйте коллег.


ссылка на оригинал статьи https://habr.com/ru/companies/ru_mts/articles/743918/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *