23 мая 2023

🐍 20 важных концепций в Python, которые помогут вам стать более эффективным разработчиком

iOS-developer, ИТ-переводчица, пишу статьи и гайды.
В этой статье мы рассмотрим фишки Python, которые поднимут ваши навыки на новый уровень: декораторы, магические методы в классах, лямбда-функции, распаковку кортежей с помощью одной строки кода и многое другое.
🐍 20 важных концепций в Python, которые помогут вам стать более эффективным разработчиком
Данная статья является переводом. Автор: Liu Zuo Lin. Ссылка на оригинал.

1. Распаковка кортежа + Распаковка кортежа с *

        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']
    

Мы можем добавить * перед переменными, чтобы распаковать все остальное в эту переменную.

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

        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}
    

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

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

        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 в ОДНУ строку, используя тернарный оператор.

4. Магические методы в классах Python

        class Dog():
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def __str__(self):
    return f'Dog(name={self.name}, age={self.age})'

  def __gt__(self, otherDog):
    return self.age > otherDog.age
    

__ init __ , __str__ и __ gt __ являются магическими методами, которые позволяют нам работать по-особенному с нашими объектами Dog.

        dog = Dog('rocky', 4)
print(dog)    # Dog(name=rocky, age=4)
    

Магический метод __str__ определяет, что возвращается, когда мы вызываем str(dog), который вызывается, когда мы печатаем объекты Dog.

        dog1 = Dog('rocky', 4)
dog2 = Dog('fifi', 2)

print(dog1 > dog2)      # True
    

Магический метод __ gt __ определяет, что происходит, когда мы сравниваем двух собак с помощью оператора >.

5. * *args и **kwargs

        def test(a, b, *args):
  print(f'{a=} {b=} {args=}')

test(1,2,3,4,5)  # a=1 b=2 args=(3,4,5)
    

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

        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}
    

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

6. Работа с несколькими .py файлами

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

# main.py
from helper import test123

test123()    # test123 is called
    

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

7. if __name__ == ‘__main__’

        # 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

    

Строка if __name__ == '__main__' оценивается как True в файле .py, только если мы запустим файл .py файл напрямую. Мы используем эту строку, чтобы случайно не запустить строки кода, которые мы не собираемся запускать.

8. True и False значения

        # 0, если falsy, и оценивается как False
if 0: print('this wont print')

# ненулевые числа truthy и оцениваются как True
if 1: print('this prints')
if 2: print('this prints')
if 100: print('this prints')
if -1: print('this prints')
if 3.14: print('this prints')

# пустые последовательности являются falsy и оцениваются как False
if '': print('this wont print')
if []: print('this wont print')
if {}: print('this wont print')
if set(): print('this wont print')

# непустые последовательности являются truthy и оцениваются как True
if 'a': print('this prints')
if [1]: print('this prints')
if {2:3}: print('this prints')
if {1,2}: print('this prints')

# None является falsy и оценивается как False
obj = None
if obj: print('this wont print')

# объекты являются truthy и оцениваются как True
obj = Dog()
if obj: print('this prints')
    

9. break vs continue vs pass

        for i in [1,2,3,4,5]:
  if i == 3:
    break

  print(i)

# this prints 1 and 2
    

break полностью останавливает цикл for/while. Никакой другой итерации не происходит.

        for i in [1,2,3,4,5]:
  if i == 3:
    continue

  print(i)

# this prints 1, 2, 4 and 5
    

continue пропускает ОДНУ итерацию. Другие итерации все еще происходят позже.

        for i in [1,2,3,4,5]:
  if i == 3:
    pass

  print(i)

# this prints 1, 2, 3, 4 and 5

    

pass абсолютно ничего не делает.

10. Блоки try, except, finally

        try:
   # код, в котором потенциально могут быть вызваны исключения
except:
   # этот блок выполняется, если в блоке try возникает исключение
finally:
   # вещи здесь будут выполняться ВСЕГДА
    

Блоки try-except-finally позволяют нам обрабатывать вещи, когда в нашем коде возникают ошибки и исключения (вместо просто сбоя)

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

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

Некоторые простые в освоении библиотеки на Python:

  • Python FastAPI – это позволяет нам очень легко создавать API.
  • Python Flask – мы также можем создавать API с помощью Flask и даже простые веб-приложения.

12. Декораторы

Я узнал об этом ОЧЕНЬ поздно на своем пути развития в Python и игнорировал любой синтаксис @decorator, который я видел. Но лучше понимать, что происходит в вашем коде.

        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}'
    

Декораторы – это функции, которые: 1) принимают другую функцию, 2) настраивают работу функции и 3) возвращают другую функцию. Когда мы помещаем @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. Из-за нашего декоратора наша функция greet ведет себя по-другому, и теперь у нее есть дополнительный ! после возвращаемого значения.

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

        def simple_generator():
  yield 'apple'
  yield 'orange'
  yield 'pear'

for fruit in simple_generator():
  print(fruit)

# apple orange pear
    

Ключевое слово yield похоже на ключевое слово return. За исключением того, что функция не останавливается полностью после чего-то.

Функция, содержащая ключевое слово yield, становится функцией-генератором и может иметь несколько выходных данных.

14. Цепочка методов

На самом деле я узнал об этом намного позже, чем должен был.

        s = ' APPLE ORANGE PEAR '
s = s.strip()    # s is now 'APPLE ORANGE PEAR'
s = s.lower()    # s is now 'apple orange pear'
s = s.split()    # s is now ['apple', 'orange', 'pear']
    

Некоторый общий код для очистки строки.

        s = ' APPLE ORANGE PEAR '
s = s.strip().lower().split()

# s is now ['apple', 'orange', 'pear']
    

Мы можем объединить несколько методов в одну строку, чтобы сэкономить несколько строк кода.

15. Базовое машинное обучение – регрессия и классификация

Прежде чем я узнал (на базовом уровне), как работает машинное обучение, я думал, что это какая-то магия.

После того, как я узнал, как работает машинное обучение (на базовом уровне), я подумал: «О, хорошо, так это своего рода автоматическая статистика с помощью компьютера». Это больше не было волшебной магией.

Машинное обучение – это огромная область, но обычно мы начинаем с обучения с учителем, точнее, с классификации и регрессии. В качестве стартового набора попробуйте scikit-learn, библиотеку Python, которая выполняет за вас весь код машинного обучения и позволяет вам просто использовать их функции и классы.

16. Основные структуры данных и алгоритмы

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

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

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

Если устраиваешься кодером – ни один собес не пройдет без них. Кстати, у «Библиотеки программиста» как раз есть курс «Алгоритмы и структуры данных», который помогает подготовиться к алгоритмическому собеседованию в крупные IT-компании.

17. Различные структуры данных и когда их использовать

В Python есть несколько встроенных структур данных.

        # упорядоченный набор элементов
list1 = [1,2,3]

# неизменяемый список. мы можем использовать это как ключ словаря
tuple1 = (1,2,3)

# O(1) при доступе к значению с помощью ключа
dict1 = {'apple':4, 'orange':5}

# неупорядоченная коллекция, содержащая только уникальные элементы
# O(1) при проверке существования элемента внутри множества
set1 = {1,2,3}

# неизменяемое множество. мы можем использовать это как ключ dict
frozenset1 = frozenset({1,2,3})
    

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

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

        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)
    

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

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

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

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

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

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

if score > 100:
  raise ScoreException()
    

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

20. Многопроцессорность в Python

Встроенный модуль multiprocessing в Python позволяет нам запускать более одной функции одновременно.

        import 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) работает сама по себе

Материалы по теме

Источники

Знаете интересные фишки языка Python? Поделитесь ими в комментариях!

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ