Для чего питон нужен: Где используется язык программирования Python – Для чего нужен Python? — Хабр Q&A

Содержание

Программирование на Python: нет смысла идти на платные курсы пока не разберетесь в бесплатных

Python ча­сто со­ве­ту­ют изу­чать тем, кто ни­ко­гда рань­ше не про­грам­ми­ро­вал. Одно из его пре­иму­ществ — уни­вер­саль­ность, за счёт ко­то­рой он ис­поль­зу­ет­ся про­фес­си­о­на­ла­ми в раз­ных об­ла­стях: от жур­на­ли­сти­ки до про­дакт-ме­недж­мен­та. Его мож­но при­ме­нять для ре­ше­ния ру­тин­ных за­дач: на­при­мер, что­бы ви­зу­а­ли­зи­ро­вать боль­шой объ­ём дан­ных или со­став­лять спис­ки дел и по­ку­пок. Ав­тор и ме­не­джер про­грам­мы «Ана­лиз дан­ных» в Ян­декс.Прак­ти­ку­ме Анна Чу­ви­ли­на рас­ска­за­ла как оп­ти­ми­зи­ро­вать свой быт и ра­бо­ту при по­мо­щи про­грам­ми­ро­ва­ния, ка­кие биб­лио­те­ки (шаб­ло­ны ре­ше­ний) мо­гут ис­поль­зо­вать но­вич­ки и как вы­брать курс по изу­че­нию Python. Ма­те­ри­ал под­го­тов­лен Ака­де­ми­ей Ян­дек­са

По­че­му Python со­ве­ту­ют но­вич­кам

Одно из глав­ных пре­иму­ществ Python — низ­кий по­рог вхо­да. Код на нём ла­ко­нич­ный и обыч­но схо­ду по­ня­тен даже тем, кто изу­чал дру­гой язык. А по­дроб­ная до­ку­мен­та­ция по­мо­жет разо­брать­ся в про­грам­ми­ро­ва­нии с нуля.

Ре­сур­сы для изу­че­ния Python:

Во­круг Python сфор­ми­ро­ва­лись со­об­ще­ства эн­ту­зи­а­стов, ко­то­рые пи­шут на этом язы­ке. На­при­мер, в Москве есть груп­па Moscow Python: они про­во­дят кон­фе­рен­ции и нефор­маль­ные встре­чи и со­труд­ни­ча­ют с круп­ны­ми ИТ-ком­па­ни­я­ми.

Для Python су­ще­ству­ет объ­ём­ная си­сте­ма биб­лио­тек — го­то­вых ре­ше­ний для тех или иных за­дач. Есть как ал­го­рит­мы для ба­зо­вых ма­те­ма­ти­че­ских опе­ра­ций, так и для слож­ных за­дач: на­при­мер, рас­по­зна­ва­ния кар­ти­нок и зву­ков.

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

Важ­но по­ни­мать, что для ана­ли­за дан­ных язык про­грам­ми­ро­ва­ния — это ин­стру­мент. Ана­лиз дан­ных мож­но про­во­дить и в Ex­cel, и на бу­маж­ке, а про­грам­ми­ро­ва­ние — толь­ко один из ва­ри­ан­тов того, как мож­но ре­шать та­кие за­да­чи.

Одно из рас­про­стра­нён­ных при­ло­же­ний Python — ра­бо­та с дан­ны­ми для про­дакт-ме­недж­мен­та. Ана­лиз дан­ных поз­во­ля­ет ме­не­дже­рам по­лу­чать ин­сай­ты о по­ве­де­нии поль­зо­ва­те­лей и при­ни­мать обос­но­ван­ные ре­ше­ния. В круп­ных ком­па­ни­ях долж­но­сти ана­ли­ти­ков и про­дакт-ме­не­дже­ров обыч­но раз­де­ле­ны, но в неболь­ших про­ек­тах про­дак­там нуж­но ра­бо­тать с дан­ны­ми са­мо­сто­я­тель­но.

Как по­нять, что вам ну­жен имен­но Python

На­зы­вать его «убий­цей Ex­cel» — некор­рект­но. Мно­гие ко­ман­ды и ком­па­нии в Рос­сии ве­дут весь учёт в обыч­ных таб­ли­цах, и им это­го до­ста­точ­но. А Python ну­жен в тот мо­мент, ко­гда речь идет про дей­стви­тель­но боль­шие объ­е­мы дан­ных. На­при­мер, у Ян­декс.Му­зы­ки мно­же­ство пла­тя­щих поль­зо­ва­те­лей, и их дей­ствия еже­днев­но ге­не­ри­ру­ют ка­кие-то со­бы­тия (лай­ки и про­слу­ши­ва­ния) — и те­ра­бай­ты дан­ных. Хра­нить их в таб­лич­ке Ex­cel — из раз­ря­да фан­та­сти­ки.

В Python про­ще де­лать ин­тер­ак­тив­ную и слож­ную ви­зу­а­ли­за­цию или про­во­дить вы­чис­ле­ния — для это­го су­ще­ству­ют биб­лио­те­ки вро­де Seaborn, mat­plot и Plotly. В Ex­cel есть встро­ен­ный ап­па­рат для ре­ше­ния ма­те­ма­ти­че­ских за­дач (на­при­мер, ра­бо­ты с дан­ны­ми), но для него нуж­но за­по­ми­нать мно­го на­зва­ний опе­ра­ций — и ра­бо­та­ет он до­воль­но непо­во­рот­ли­во. Кро­ме того, в Python мож­но быст­рее и с раз­ных сто­рон по­смот­реть на дан­ные. Ре­грес­сию мож­но по­стро­ить и в Ex­cel, но за­чем, ко­гда в Python есть для это­го го­то­вые биб­лио­те­ки?

©

Jefferson Santos / Unsplash


Для ста­ти­сти­че­ских рас­че­тов мож­но ис­поль­зо­вать R — люди с ма­те­ма­ти­че­ским об­ра­зо­ва­ни­ем обыч­но осва­и­ва­ют его быст­рее, чем Python. Од­на­ко боль­шин­ству бу­дет про­ще на­чать с Python.

Для раз­ных за­дач ана­ли­за дан­ных су­ще­ству­ют ко­ро­боч­ные ре­ше­ния. На­при­мер, Am­pli­tude (для про­дук­то­вой ана­ли­ти­ки), Mix­panel (для ана­ли­за по­ве­де­ния поль­зо­ва­те­лей) Ян­декс.Мет­ри­ка и Google An­a­lyt­ics. При этом их ис­поль­зо­ва­ние ча­сто плат­ное.

Где при­ме­нять Python, если вы не раз­ра­бот­чик

По­ми­мо ана­ли­за дан­ных у язы­ка есть и бо­лее про­стые при­ло­же­ния. Так, в учеб­ни­ках по Python ча­сто встре­ча­ет­ся за­да­ча с рас­сыл­ка­ми. В ней нуж­но соз­дать рас­сыл­ку, на­при­мер, для лю­дей, ко­то­рые не сда­ли день­ги на ре­монт — най­дя их дан­ные в Ex­cel-таб­ли­це. С по­мо­щью та­ко­го скрип­та мож­но разо­слать пись­ма по шаб­ло­ну — и име­на бу­дут под­став­ле­ны ав­то­ма­ти­че­ски.

Python — про ав­то­ма­ти­за­цию ру­тин­ных за­дач. На­при­мер, мож­но за­пу­стить скрипт, ко­то­рый под­став­ля­ет па­ро­ли — и он ав­то­ма­ти­че­ски от­кро­ет за­па­ро­лен­ные стра­ни­цы или пап­ки. Есть ал­го­рит­мы для того, что­бы ав­то­ма­ти­че­ски со­зда­вать спис­ки по­ку­пок или пе­ре­име­но­вы­вать фо­то­гра­фии опре­де­лён­ным об­ра­зом.

Люди, ко­то­рые уме­ют пи­сать код, при­ду­мы­ва­ют та­кие вещи «на ав­то­ма­те». На­при­мер, мар­ке­то­ло­ги мо­гут за­пу­стить скрипт для по­стро­е­ния во­ро­нок про­даж. А те­сти­ров­щи­ки — на­пи­сать ал­го­ритм, ко­то­рый бу­дет под­став­лять дан­ные в фор­мы и те­сти­ро­вать при­ло­же­ния.

Если го­во­рить про ана­лиз дан­ных, то мно­гие на­чи­на­ют осва­и­вать его из лю­бо­пыт­ства — что­бы най­ти ин­сай­ты в сфе­ре, ко­то­рую пока не ис­сле­до­ва­ли. На­при­мер, мож­но опре­де­лить со­ци­аль­ные про­бле­мы сво­е­го ре­ги­о­на, ана­ли­зи­руя опуб­ли­ко­ван­ную ста­ти­сти­ку. А если вы хо­ти­те че­рез ка­кое-то вре­мя по­пасть на ста­жи­ров­ку или на ра­бо­ту, где ну­жен ана­лиз дан­ных, то та­кой кейс по­мо­жет вам по­ка­зать свои на­вы­ки. На­чать мож­но с про­стых, стан­дарт­ных про­ек­тов, ко­то­рые обыч­но пред­ла­га­ют тем, кто изу­ча­ет Python.

Что нуж­но, что­бы вы­учить Python

Из ма­те­ма­ти­че­ско­го ап­па­ра­та кро­ме ба­зо­вой ариф­ме­ти­ки для про­грам­ми­ро­ва­ния ни­че­го не нуж­но. Что­бы при­ду­мать, ка­кой ал­го­ритм ис­поль­зо­вать для ре­ше­ния той или иной за­да­чи, важ­но струк­тур­ное мыш­ле­ние — но это не ма­те­ма­ти­че­ская ком­пе­тен­ция. Па­ра­докс в том, что и раз­ви­вать его нуж­но с по­мо­щью ре­гу­ляр­ной ра­бо­ты с за­да­ча­ми — важ­но быть го­то­вым про­си­деть над, ка­за­лось бы, три­ви­аль­ным за­да­ни­ем несколь­ко ча­сов и не от­ча­ять­ся.

Для ана­ли­за дан­ных, по­ми­мо школь­ной ма­те­ма­ти­ки, по­на­до­бят­ся зна­ния ма­те­ма­ти­че­ской ста­ти­сти­ки и тео­рии ве­ро­ят­но­сти. На­чи­на­ю­ще­му спе­ци­а­ли­сту важ­нее все­го осво­ить ба­зо­вые по­ня­тия: уметь про­ве­рять ги­по­те­зы, знать, что та­кое до­ве­ри­тель­ные ин­тер­ва­лы, чем от­ли­ча­ют­ся ме­ди­а­на и мода, по­ни­мать, как обо­зна­чать со­бы­тия и их ве­ро­ят­но­сти.


Ма­те­ри­а­лы по ма­те­ма­ти­ке:

Тем, кто хо­чет за­ни­мать­ся ана­ли­зом дан­ных (как про­фес­си­о­наль­но, так и для себя), важ­но раз­вить кри­ти­че­ское мыш­ле­ние. На­при­мер, нуж­но са­мо­му вы­де­лять кри­те­рии для срав­не­ния объ­ек­тов: тут нет ка­ко­го-то стан­дарт­но­го ре­ше­ния. Ещё важ­но схо­ду ви­деть за­ко­но­мер­но­сти и ано­ма­лии в дан­ных.

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

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

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

©

Fatos Bytyqi / Unsplash


Как вы­брать об­ра­зо­ва­тель­ную про­грам­му

Вы­би­рая об­ра­зо­ва­тель­ную про­грам­му, важ­но об­ра­тить вни­ма­ние на пре­по­да­ва­те­лей, ко­то­рые его ве­дут или со­зда­ва­ли для него кон­тент, — мож­но по­смот­реть их про­фи­ли на Face­book и узнать про про­фес­си­о­наль­ный опыт.

Что ка­са­ет­ся цены, то по мо­е­му опы­ту, ка­че­ство кур­са не все­гда с ней кор­ре­ли­ру­ет — по­это­му ори­ен­ти­ро­вать­ся нуж­но на то, сколь­ко вам ком­форт­но по­тра­тить на обу­че­ние.

Так­же сто­ит чёт­ко сфор­му­ли­ро­вать то, что хо­чет­ся по­лу­чить в ре­зуль­та­те, — и сде­лать это клю­че­вым кри­те­ри­ем для вы­бо­ра. Бы­ва­ют слу­чаи, ко­гда сту­ден­ты при­хо­дят на курс по ана­ли­зу дан­ных для ме­не­дже­ров и ожи­да­ют за­ня­тия по про­грам­ми­ро­ва­нию — а их учат об­щать­ся с ана­ли­ти­ка­ми и рас­ска­зы­ва­ют об­щие вещи про то, как внед­рять ана­лиз дан­ных. За­ча­стую про­бле­ма не в пло­хой ор­га­ни­за­ции или пре­по­да­ва­те­лях, а в том, что че­ло­век сам не про­ве­рил, со­от­вет­ству­ет ли про­грам­ма его за­да­чам. Пра­ви­ло с по­ста­нов­кой це­лей ра­бо­та­ет не толь­ко на вы­бор про­грам­мы, но и на обу­че­ние в це­лом — не сто­ит осва­и­вать язык про­грам­ми­ро­ва­ния, что­бы по­ста­вить га­лоч­ку.

Возможности Python 3, достойные того, чтобы ими пользовались / RUVDS.com corporate blog / Habr

Многие программисты начали переходить со второй версии Python на третью из-за того, что уже довольно скоро поддержка Python 2 будет прекращена. Автор статьи, перевод которой мы публикуем, отмечает, что основной объём Python 3-кода, который ему доводилось видеть, выглядит как код со скобками, написанный на Python 2. По его словам, он и сам грешит чем-то подобным. Здесь он приводит примеры некоторых замечательных возможностей, доступных лишь тем, кто пользуется Python 3. Он надеется, что эти возможности облегчат жизнь тем, кто о них узнает.

Все примеры, приведённые в этом материале, написаны с использованием Python 3.7. В описании каждой возможности имеются сведения о минимальной версии Python, необходимой для её применения.

Форматные строки (3.6+)


Без использования строк сложно написать что-то полезное на любом языке программирования. Но для эффективной работы со строками разработчику нужны удобные инструменты. Такие инструменты, которые позволяют оперировать сложными структурами, не теряя при этом душевного равновесия. Большинство Python-разработчиков пользуется методом format:
user = "Jane Doe"
action = "buy"
log_message = 'User {} has logged in and did an action {}.'.format(
  user,
  action
)
print(log_message)
# User Jane Doe has logged in and did an action buy.

Python 3, наряду с методом format, поддерживает форматные строки (f-strings, f-строки). Они представляют собой гибкий инструмент для выполнения различных манипуляций со строками. Вот как выглядит предыдущий пример, переписанный с использованием форматных строк:
user = "Jane Doe"
action = "buy"
log_message = f'User {user} has logged in and did an action {action}.'
print(log_message)
# User Jane Doe has logged in and did an action buy.

Модуль pathlib (3.4+)


Форматные строки — замечательная технология, но для работы с некоторыми строками, вроде путей к файлам, созданы специальные инструменты, сильно упрощающие манипуляции с ними. В Python 3 имеется модуль pathlib, который представляет собой удобную абстракцию для работы с путями к файлам. Если вы пока не уверены в полезности этого модуля для решения ваших задач — взгляните на этот материал.
from pathlib import Path
root = Path('post_sub_folder')
print(root)
# post_sub_folder
path = root / 'happy_user'
# Делаем путь абсолютным
print(path.resolve())
# /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user

Аннотации типов (3.5+)


Что лучше — статическая или динамическая типизация? Пожалуй, почти каждый программист имеет собственный ответ на этот непростой вопрос. Я оставляю на усмотрение читателей то, как именно они типизируют свои программы. Но я считаю, что всем полезно будет хотя бы знать о том, что Python 3 поддерживает аннотации типов.
def sentence_has_animal(sentence: str) -> bool:  return "animal" in sentence sentence_has_animal("Donald had a farm without animals") # True

Перечисления (3.4+)


Python 3 поддерживает, благодаря классу Enum, простой механизм работы с перечислениями. Перечисления удобно использовать для хранения списков констант. Константы, в противном случае, оказываются беспорядочно разбросанными в коде.
from enum import Enum, auto
class Monster(Enum):
    ZOMBIE = auto()
    WARRIOR = auto()
    BEAR = auto()
    
print(Monster.ZOMBIE)
# Monster.ZOMBIE

Из документации по Python 3 можно узнать о том, что перечисление — это набор символических имён (членов), привязанных к уникальным, неизменным значениям. Члены одного перечисления можно сравнивать на идентичность. Перечисления можно обходить.
for monster in Monster:
    print(monster)
# Monster.ZOMBIE
# Monster.WARRIOR
# Monster.BEAR

Встроенный LRU-кэш (3.2+)


В наши дни механизмы кэширования применяются практически во всех программных и аппаратных системах. Python 3 значительно упрощает кэширование благодаря декоратору lru_cache, который реализует алгоритм LRU-кэширования (Least Recently Used).

Ниже показана функция, которая вычисляет числа Фибоначчи. Эта функция вынуждена по много раз выполнять одни и те же операции в ходе рекурсивных вызовов. В результате оказывается, что её производительность можно улучшить благодаря кэшированию.

import time
def fib(number: int) -> int:
    if number == 0: return 0
    if number == 1: return 1
    
    return fib(number-1) + fib(number-2)
start = time.time()
fib(40)
print(f'Duration: {time.time() - start}s')
# Duration: 30.684099674224854s

Теперь используем lru_cache для оптимизации этой функции (такая техника оптимизации называется мемоизацией). В результате время выполнения функции, которое раньше измерялось секундами, теперь измеряется наносекундами.
from functools import lru_cache @lru_cache(maxsize=512) def fib_memoization(number: int) -> int:    if number == 0: return 0    if number == 1: return 1        return fib_memoization(number-1) + fib_memoization(number-2) start = time.time() fib_memoization(40) print(f'Duration: {time.time() - start}s') # Duration: 6.866455078125e-05s

Распаковка итерируемых объектов (3.0+)


При распаковке итерируемых объектов можно использовать переменные, перед именами которых ставят звёздочку. В такие переменные попадает всё то, что не попало в другие переменные. Так, в следующем примере в переменные head и tail попадают первое и последнее значения из списка, сформированного командой range(5). В переменную body попадает всё то, что находится между первым и последним значением.
head, *body, tail = range(5)
print(head, body, tail)
# 0 [1, 2, 3] 4
py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split()
print(py)
print(filename)
print(cmds)
# python3.7
# script.py
# ['-n', '5', '-l', '15']
first, _, third, *_ = range(10)
print(first, third)
# 0 2

Классы данных (3.7+)


В Python 3 появились классы данных (data classes). Они дают программисту достаточно большую свободу действий. Их можно использовать для уменьшения объёма шаблонного кода. Дело в том, что декоратор dataclass автоматически генерирует специальные методы, такие как __init__() и __repr__(). В официальном тексте соответствующего предложения они описаны как «изменяемые именованные кортежи со значениями по умолчанию». Вот пример создания класса без использования декоратора dataclass:
class Armor:
    
    def __init__(self, armor: float, description: str, level: int = 1):
        self.armor = armor
        self.level = level
        self.description = description
                 
    def power(self) -> float:
        return self.armor * self.level
    
armor = Armor(5.2, "Common armor.", 2)
armor.power()
# 10.4
print(armor)
# <__main__.Armor object at 0x7fc4800e2cf8>

Вот то же самое, но уже написанное с применением dataclass:
from dataclasses import dataclass
@dataclass
class Armor:
    armor: float
    description: str
    level: int = 1
    
    def power(self) -> float:
        return self.armor * self.level
    
armor = Armor(5.2, "Common armor.", 2)
armor.power()
# 10.4
print(armor)
# Armor(armor=5.2, description='Common armor.', level=2)

Поддержка папок пакетов без файла __init__.py (3.3+)


Один из способов структурирования Python-кода заключается в использовании пакетов (пакеты размещаются в папках, в которых есть файл __init__.py). Вот пример из официальной документации:
sound/                          Пакет верхнего уровня
      __init__.py               Инициализация пакета sound
      formats/                  Подпакет для преобразования форматов файлов
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Подпакет для звуковых эффектов
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Подпакет для фильтров
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

При использовании Python 2 в каждой из папок, упомянутых в примере, должен был быть файл __init__.py. Благодаря этому файлу папка воспринимается в виде Python-пакета. В Python 3, с появлением возможности Implicit Namespace Packages, наличие в папках подобных файлов больше не является обязательным.
sound/                          Пакет верхнего уровня
      __init__.py               Инициализация пакета sound
      formats/                  Подпакет для преобразования форматов файлов
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Подпакет для звуковых эффектов
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Подпакет для фильтров
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Надо отметить, что на самом деле всё не так просто. А именно, в соответствии с этой официальной спецификацией, файл __init__.py всё ещё нужен для обычных пакетов. Если убрать его из папки, то пакет превращается в так называемый пакет пространства имён, к которому применяются дополнительные ограничения.

Итоги


В этом материале рассмотрены далеко не все интересные возможности Python 3, но мы надеемся, что вы нашли здесь что-то полезное. Код примеров можно найти в этом репозитории.

Уважаемые читатели! Какие возможности Python 3 вы добавили бы в приведённый здесь список?

Что можно делать с Python?

У вас получилось: вы закончили курсы, или дочитали книгу, которая дает вам базу для программирования в Python. Вы освоили списки, словари, классы, может даже некоторые объектно-ориентированные концепции.

Мы собрали ТОП Книг для Python программиста которые помогут быстро изучить язык программирования Python. Список книг: Книги по Python

И что дальше?

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

Содержание:

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

Что другие делают в Python?

Вы, наверное, думаете, что люди создают в Python в реальной жизни? Для начала, давайте быстренько пройдемся по крупным компаниям, которые используют данный язык.

Google, к примеру, использовали Python с самого начала, и сегодня он занимает место ведущих гигантов среди языков, ориентированных на серверную сторону. Гвидо ван Россум, добрый пожизненный диктатор Python (уже нет) даже работал нам на протяжении нескольких лет, наблюдая за тем, как развивается язык.

В Instagram любят Python за его простоту. Сервис известен «самым большим развертыванием веб-фреймворка Django, который полностью написан на Python».

Spotify использует язык из-за его сервисов анализа данных и бэкенда. Согласно команде разработчиков, простота использования Python позволяет достичь молниеносной скорости разработки. Spotify выполняет тонны анализов, чтобы собирать рекомендации своим пользователям, так что им нужно что-нибудь, что может выполнять такую работу быстро. Python – это решение!

Что я могу делать в Python?

Начиная с веб разработки до работы с научными данными, машинным обучением, и пр., приложения Python не имеют границ. Рассмотрим несколько проектов, которые помогут вам развить ваши навыки работы с Python.

#1: Автоматизация нудных дел

Это ресурс по «практическому программированию для начинающих». Как и говорится в заголовке, с этой книгой вы можете узнать, как автоматизировать скучные процессы, такие как обновление электронных таблиц, или переименовывать файлы на компьютере. Это отличная отправная точка для тех, кто уже освоил основы Python.Что можно делать с Python?

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

#2: Держать руку на курсе Биткоина

Похоже, что сегодня о Bitcoin Python говорят все. С тех пор, как в декабре 2017, когда курс почти поднялся до отметки в 20 000 долларов, криптовалюта стала на слуху у миллионов. Цена продолжает колебаться, но многие считают инвестиции целесообразными.

Если вы хотите обогатиться на виртуальном золоте и хотите знать, когда делать следующий шаг, то вам нужно иметь представление о лучших ценах на bitcoin. Это руководство может научить вас, как использовать навыки работы в Python, чтобы построить собственную систему уведомлений о курсе Bitcoin.

Основа этого проекта – это создание IFTTT (if this, then that) апплетов. Вы узнаете, как использовать библиотеку requests для отправки запросов HTTP и как использовать webhook для подключения вашего приложения к внешним сервисам.

Этот проект – отличная отправная точка для начинающего питониста, который заинтересован в крипте. Сервис, который вы построите с данным руководством может быть расширен под другие валюты, так что если вы также рассматриваете Ethereum – двери открыты!

#3: Создание калькулятора

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

Если вам интересен UX\UI дизайн, то это руководство вам понравится. Вы будете работать с модулем tkinter, стандартным пакетом графического пользовательского интерфейса, который поставляется вместе с Python.

Модуль tkinter – это обертка вокруг Tcl/Tk, комбинация скриптового языка Tcl и расширения фреймворка графического пользовательского интерфейса Tk. Если у вас есть установленный Python, то у вас уже есть готовый к использованию tkinter. Вам нужно сделать простой вызов перед началом:

<span>from</span> <span>tkinter</span> <span>import</span> <span>*</span>

<span>from</span> <span>tkinter</span> <span>import</span> <span>*</span>

После проведения установки, вы можете начать работу с постройкой своего первого GUI калькулятора в Python.
Попрактикуйтесь в использовании модуля tkinter и наблюдайте за тем, как ваше виденье материализуется на экране. После того, как вы окрепнете, вы можете начать работать с другими GUI инструментами Python. Ознакомьтесь к официальной документацией GUI программирования в Python для дополнительной информации.

#4: Майнинг данных Twitter

Благодаря интернету, и (все чаще и чаще) интернету вещей (IoT) – у нас есть доступ к огромному количеству данных, о которых не могли мечтать всего десять лет назад. Аналитика – это огромная часть любой сферы, которая связана с данными. О чем люди разговаривают? Какие шаблоны видны в их поведении?

Твиттер – отличное место, чтобы получить ответы на эти вопросы. Если вам интересен анализ данных, тогда майнинг данных в Twitter – отличный способ попробовать свои навыки в Python, чтобы ответить на вопросы об окружающем мире.

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

Вы увидите, как использовать Tweepy для фильтрации твитов, которые вы хотите вытягивать, TextBlob для подсчета настроения этих твитов, Elasticsearch для анализа содержимого этих твитов и Kibana для показа результатов. По окончанию данного руководства, вы уже будете готовы к тому, чтобы заняться другими проектами, которые используют Python для обработки текстов и распознавания речи.

#5: Создание микроблога с помощью Flask

Похоже, что у каждого сегодня есть блог, и нет ничего плохого в том, чтобы иметь собственный уютный хаб онлайн. С развитием Twitter и Instagram, микроблоги стали чрезвычайно популярными. В этом проекте Мигеля Гринерга, вы научитесь создавать собственный микроблог.

Он называется «Мега-руководство Flask», и однозначно соответствует названию. Проработав 23 главы, вы получите глубокое представление о веб-фреймворке Flask. К концу проекта, вы сможете создать полностью работающее веб приложение.
Вам не нужно знать что-либо о Flask, чтобы приступить к делу, так что это идеально для тех, у кого чешутся руки, чтобы приступить к веб разработке.

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

#6: Создание блокчейна

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

Вы можете получить лучшее представление о том, как это работает, построив свой блокчейн! Руководство Hackernoon поможет вам реализовать блокчейн с нуля. К концу проекта, вы получите глубокое представление того, как работает эта технология транзакций.

Вы будете работать с HTTP клиентами и библиотекой requests. После установки веб-фреймворка Flask, вы сможете использовать запросы HTTP и взаимодействовать со своим блокчейном в интернете.

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

#7: Разбираемся с лентой Twitter

Интересует постройка веб приложений, но не хватает уверенности, чтобы начать мега-проект? Не беспокойтесь, мы кое-что подготовили для вас. С нами вы сможете научиться создавать простое веб приложение всего за несколько часов.

Боб Белдерброс делится кейсом, где он создал 40th PyBites Code Challenge, в котором участникам нужно было построить простое веб приложение для лучшей навигации по ленте новостей Daily Python Tip в Твиттере. Вы можете пройтись по результатам данного челенджа и ознакомиться с кодом.

Вместо Flask, вы будете использовать микро веб-фреймворк Bottle. Он славится тем, что является слабо зависимым решением для быстрого создания приложений. Так как он был разработан таким образом, чтобы быть легким и простым в использовании, вы сможете получить свое приложение практически мгновенно.
Вы также сможете работать с модулем Tweepy, чтобы загружать данные из API Твиттера. Вы сможете хранить данные в базе SQLAlchemy или Peewee, так что заодно получите небольшую практику в запросах SQL.

#8: Играйте в PyGames

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

Библиотека Pygame заметно упрощает разработку собственных игр. Он включает в себя практически все необходимое, чтобы вы могли приступить к разработке игр.

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

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

#9: Выберите свое собственное приключение

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

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

Если вы хотите, чтобы ваша история вышла на новый уровень, вы можете использовать движок, вроде RenPy, чтобы добавить звуки и изображения в вашу игру, создав визуальную новеллу с полным погружением. (После этого, вы можете выложить игру в Steam и посмотреть, как она расходится! Лучший способ получить отзыв о вашей работе – создать собственный релиз на мировом рынке.)

#10: Скажите “Привет, мир!” машинному обучению

Машинное обучение может быть фундаментальной областью в понимании искусственного интеллекта. Однако, в этой сфере легко запутаться, так как она постоянно развивается и меняется.
К счастью, в вашем распоряжении имеются онлайн ресурсы, которые могут помочь освоиться, перед тем как нырнуть с головой в мир под названием data science. Это руководство создано Джейсоном Браунли, и является хорошим примером введением в использование Python для машинного обучения.

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

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

Когда вы будете уверены в том, что можно нырять с головой, можете ознакомиться с этими руководствами, где вы сможете научиться анализировать отпечатки, создавать визуализации, распознавать речь и лица, и все это в Python!

#11: Бросаем вызов!

Если вы не уверены в том, что готовы окунаться в некоторые крупные проекты, упомянутые ранее, при этом мелкие вас не очень интересуют, вы можете думать: а чем еще можно заняться?

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

У вас будет шанс разработать решения, которые имеют смысл для вас, при этом у вас есть возможность углубиться в язык Python при помощи подсказок. Так вы получите представление о том, какие модули вам нужно импортировать, чтобы решить проблему.

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

Чтобы начать, попробуйте одно из следующих, чтобы оценить свои силы:

  • Python Challenge. Более 20 доступных уровней. Создавайте простые скрипты в Python, чтобы решить уровень. По интернету есть разбросанные подсказки, но старайтесь искать решение самостоятельно!
  • PyBites Code Challenge. Включает в себя 50 задач, и количество растет! Эти задачи направлены на то, чтобы вы научились работать в Python для создания приложений, которые будут решать определенные проблемы.

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

Книга Python Tricks – это отличный источник информации, который поможет при работе с задачами. В книге рассматриваются малоизвестные части Python, на основании которых и формируются задачи.

Чего (скорее всего) не стоит делать в Python?

Очевидно, что Python – чрезвычайно универсальный язык, с которым вы можете делать массу вещей. Но вы не можете делать буквально всё. Фактически, есть определенные сферы, на которые Python не рассчитан.

С точки зрения интерпретируемого языка, у Python есть проблемы со взаимодействия с низкоуровневыми устройствами, такими как драйверами устройств. Например, у вас будут проблемы, если вы захотите написать операционную систему только на Python. Вам лучше связать его с С или С++ для низкоуровневых приложений.

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

Что если вашей идеи нет в этом списке?

Ничего страшного! Этот список вряд ли можно назвать исчерпывающим: существует огромное количество других инструментов и приложений, которые вы можете построить в Python, которые мы не рассмотрели в данной статье. Не думайте, что ваши идеи должны как-либо ограничиваться данным списком. Это просто база, с которой вы можете начать.

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

Что делать дальше?

Ну, вот и все! Одиннадцать путей от новичка в Python до прожженного питониста!
Неважно, с чего вы хотите начать, вам открыты бесчисленные проспекты для разработки ваших навыков программирования. Начинайте с чего угодно! Родилась идея, которой нет в этом списке? Поделитесь в комментариях! Вы можете предложить идеальный проект для программиста-побратима.

Если вы застряли и ищете толчок в нужном направлении, поговорите об этом! Программирование не обязательно должно быть одиночным делом.

Если вы ищете способ задать вопрос и получить быстрый ответ от профессионалов – Python Форум всегда свободен. Это частное сообщество поможет вам найти контакт с теми, кто поможет вам пройти через возникшие стены, на которые вы наткнулись, работая в Pyhton.

Python — это медленно. Почему? / RUVDS.com corporate blog / Habr

В последнее время можно наблюдать рост популярности языка программирования Python. Он используется в DevOps, в анализе данных, в веб-разработке, в сфере безопасности и в других областях. Но вот скорость… Здесь этому языку похвастаться нечем. Автор материала, перевод которого мы сегодня публикуем, решил выяснить причины медлительности Python и найти средства его ускорения.



Общие положения


Как Java, в плане производительности, соотносится с C или C++? Как сравнить C# и Python? Ответы на эти вопросы серьёзно зависят от типа анализируемых исследователем приложений. Не существует идеального бенчмарка, но, изучая производительность программ, написанных на разных языках, неплохой отправной точкой может стать проект The Computer Language Benchmarks Game.

Я ссылаюсь на The Computer Language Benchmarks Game уже больше десяти лет. Python, в сравнении с другими языками, такими, как Java, C#, Go, JavaScript, C++, является одним из самых медленных. Сюда входят языки, в которых используется JIT-компиляция (C#, Java), и AOT-компиляция (C, C++), а также интерпретируемые языки, такие, как JavaScript.

Тут мне хотелось бы отметить, что говоря «Python», я имею в виду эталонную реализацию интерпретатора Python — CPython. В этом материале мы коснёмся и других его реализаций. Собственно говоря, здесь мне хочется найти ответ на вопрос о том, почему Python требуется в 2-10 раз больше времени, чем другим языкам, на решение сопоставимых задач, и о том, можно ли сделать его быстрее.

Вот основные теории, пытающиеся объяснить причины медленной работы Python:

  • Причина этого — в GIL (Global Interpreter Lock, глобальная блокировка интерпретатора).
  • Причина в том, что Python — это интерпретируемый, а не компилируемый язык.
  • Причина — в динамической типизации.

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

GIL


Современные компьютеры обладают многоядерными процессорами, иногда встречаются и многопроцессорные системы. Для того чтобы использовать всю эту вычислительную мощь, операционная система применяет низкоуровневые структуры, называемые потоками, в то время как процессы (например — процесс браузера Chrome) могут запускать множество потоков и соответствующим образом их использовать. В результате, например, если какой-то процесс особенно сильно нуждается в ресурсах процессора, его выполнение может быть разделено между несколькими ядрами, что позволяет большинству приложений быстрее решать встающие перед ними задачи.

Например, у моего браузера Chrome, в тот момент, когда я это пишу, имеется 44 открытых потока. Тут стоит учитывать то, что структура и API системы работы с потоками различается в операционных системах, основанных на Posix (Mac OS, Linux), и в ОС семейства Windows. Операционная система, кроме того, занимается планированием работы потоков.

Если раньше вы не встречались с многопоточным программированием, то сейчас вам нужно познакомиться с так называемыми блокировками (locks). Смысл блокировок заключается в том, что они позволяют обеспечить такое поведение системы, когда, в многопоточной среде, например, при изменении некоей переменной в памяти, доступ к одной и той же области памяти (для чтения или изменения) не могут одновременно получить несколько потоков.

Когда интерпретатор CPython создаёт переменные, он выделяет память, а затем подсчитывает количество существующих ссылок на эти переменные. Эта концепция известна как подсчёт ссылок (reference counting). Если число ссылок равняется нулю, тогда соответствующий участок памяти освобождается. Именно поэтому, например, создание «временных» переменных, скажем, в пределах областей видимости циклов, не приводит к чрезмерному увеличению объёма памяти, потребляемого приложением.

Самое интересное начинается тогда, когда одними и теми же переменными совместно пользуются несколько потоков, а главная проблема тут заключается в том, как именно CPython выполняет подсчёт ссылок. Тут и проявляется действие «глобальной блокировки интерпретатора», которая тщательно контролирует выполнение потоков.

Интерпретатор может выполнять лишь одну операцию за раз, независимо от того, как много потоков имеется в программе.

▍Как GIL влияет на производительность Python-приложений?


Если у нас имеется однопоточное приложение, работающее в одном процессе интерпретатора Python, то GIL никак на производительность не влияет. Если, например, избавиться от GIL, никакой разницы в производительности мы не заметим.

Если же, в пределах одного процесса интерпретатора Python, надо реализовать параллельную обработку данных с применением механизмов многопоточности, и используемые потоки будут интенсивно использовать подсистему ввода-вывода (например, если они будут работать с сетью или с диском), тогда можно будет наблюдать последствия того, как GIL управляет потоками. Вот как это выглядит в случае использования двух потоков, интенсивно нагружающих процессов.


Визуализация работы GIL (взято отсюда)

Если у вас имеется веб-приложение (например, основанное на фреймворке Django), и вы используете WSGI, то каждый запрос к веб-приложению будет обслуживаться отдельным процессом интерпретатора Python, то есть, у нас имеется лишь 1 блокировка на запрос. Так как интерпретатор Python запускается медленно, в некоторых реализациях WSGI имеется так называемый «режим демона», при использовании которого процессы интерпретатора поддерживаются в рабочем состоянии, что позволяет системе быстрее обслуживать запросы.

▍Как ведут себя другие интерпретаторы Python?


В PyPy есть GIL, он обычно более чем в 3 раза быстрее, чем CPython.

В Jython нет GIL, так как потоки Python в Jython представлены в виде потоков Java. Такие потоки используют возможности по управлению памятью JVM.

▍Как управление потоками организовано в JavaScript?


Если говорить о JavaScript, то, в первую очередь, надо отметить, что все JS-движки используют алгоритм сборки мусора mark-and-sweep. Как уже было сказано, основная причина необходимости использования GIL — это алгоритм управления памятью, применяемый в CPython.

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

Python — интерпретируемый язык


Мне часто приходилось слышать о том, что низкая производительность Python является следствием того, что это — интерпретируемый язык. Подобные утверждения основаны на грубом упрощении того, как, на самом деле, работает CPython. Если, в терминале, ввести команду вроде python myscript.py, тогда CPython начнёт длительную последовательность действий, которая заключается в чтении, лексическом анализе, парсинге, компиляции, интерпретации и выполнении кода скрипта. Если вас интересуют подробности — взгляните на этот материал.

Для нас, при рассмотрении этого процесса, особенно важным является тот факт, что здесь, на стадии компиляции, создаётся .pyc-файл, и последовательность байт-кодов пишется в файл в директории __pycache__/, которая используется и в Python 3, и в Python 2.

Подобное применяется не только к написанным нами скриптам, но и к импортированному коду, включая сторонние модули.

В результате, большую часть времени (если только вы не пишете код, который запускается лишь один раз) Python занимается выполнением готового байт-кода. Если сравнить это с тем, что происходит в Java и в C#, окажется, что код на Java компилируется в «Intermediate Language», и виртуальная машина Java читает байт-код и выполняет его JIT-компиляцию в машинный код. «Промежуточный язык» .NET CIL (это то же самое, что .NET Common-Language-Runtime, CLR), использует JIT-компиляцию для перехода к машинному коду.

В результате, и в Java и в C# используется некий «промежуточный язык» и присутствуют похожие механизмы. Почему же тогда Python показывает в бенчмарках гораздо худшие результаты, чем Java и C#, если все эти языки используют виртуальные машины и какие-то разновидности байт-кода? В первую очередь — из-за того, что в .NET и в Java используется JIT-компиляция.

JIT-компиляция (Just In Time compilation, компиляция «на лету» или «точно в срок») требует наличия промежуточного языка для того, чтобы позволить осуществлять разбиение кода на фрагменты (кадры). Системы AOT-компиляции (Ahead Of Time compilation, компиляция перед исполнением) спроектированы так, чтобы обеспечить полную работоспособность кода до того, как начнётся взаимодействие этого кода с системой.

Само по себе использование JIT не ускоряет выполнение кода, так как на выполнение поступают, как и в Python, некие фрагменты байт-кода. Однако JIT позволяет выполнять оптимизации кода в процессе его выполнения. Хороший JIT-оптимизатор способен выявить наиболее нагруженные части приложения (такую часть приложения называют «hot spot») и оптимизировать соответствующие фрагменты кода, заменив их оптимизированными и более производительными вариантами, чем те, что использовались ранее.

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

JIT-компилятор есть в PyPy, и, как уже было сказано, эта реализация интерпретатора Python гораздо быстрее, чем CPython. Сведения, касающиеся сравнения разных интерпретаторов Python, можно найти в этом материале.

▍Почему в CPython не используется JIT-компилятор?


У JIT-компиляторов есть и недостатки. Один из них — время запуска. CPython и так запускается сравнительно медленно, а PyPy в 2-3 раза медленнее, чем CPython. Длительное время запуска JVM — это тоже известный факт. CLR .NET обходит эту проблему, запускаясь в ходе загрузки системы, но тут надо отметить, что и CLR, и та операционная система, в которой запускается CLR, разрабатываются одной и той же компанией.

Если у вас имеется один процесс Python, который работает длительное время, при этом в таком процессе имеется код, который может быть оптимизирован, так как он содержит интенсивно используемые участки, тогда вам стоит серьёзно взглянуть на интерпретатор, имеющий JIT-компилятор.

Однако, CPython — это реализация интерпретатора Python общего назначения. Поэтому, если вы разрабатываете, с использованием Python, приложения командной строки, то необходимость длительного ожидания запуска JIT-компилятора при каждом запуске этого приложения сильно замедлит работу.

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

В результате можно сказать, что если вы, с помощью Python, пишете программу, производительность которой может улучшиться при использовании JIT-компилятора — используйте интерпретатор PyPy.

Python — динамически типизированный язык


В статически типизированных языках, при объявлении переменных, необходимо указывать их типы. Среди таких языков можно отметить C, C++, Java, C#, Go.

В динамически типизированных языках понятие типа данных имеет тот же смысл, но тип переменной является динамическим.

a = 1
a = "foo"

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

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

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

Отсутствие необходимости указывать тип переменной при её объявлении — это не та особенность языка, которая делает Python медленным. Архитектура языка позволяет сделать динамическим практически всё, что угодно. Например, во время выполнения программы можно заменять методы объектов. Опять же, во время выполнения программы можно использовать технику «обезьяньих патчей» в применении к низкоуровневым системным вызовам. В Python возможно практически всё.

Именно архитектура Python чрезвычайно усложняет оптимизацию.

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

В готовом дистрибутиве CPython нет механизмов поддержки DTrace, поэтому CPython нужно будет перекомпилировать с соответствующими настройками. Тут используется версия 3.6.6. Итак, воспользуемся следующей последовательностью действий:

wget https://github.com/python/cpython/archive/v3.6.6.zip
unzip v3.6.6.zip
cd v3.6.6
./configure --with-dtrace
make

Теперь, пользуясь python.exe, можно применять DTRace для трассировки кода. Об использовании DTrace с Python можно почитать здесь. А вот тут можно найти скрипты для измерения с помощью DTrace различных показателей работы Python-программ. Среди них — параметры вызова функций, время выполнения программ, время использования процессора, сведения о системных вызовах и так далее. Вот как пользоваться командой dtrace:
sudo dtrace -s toolkit/<tracer>.d -c ‘../cpython/python.exe script.py’

А вот как средство трассировки py_callflow показывает вызовы функций в приложении.
Трассировка с использованием DTrace

Теперь ответим на вопрос о том, влияет ли динамическая типизация на производительность Python. Вот некоторые соображения по этому поводу:

  • Проверка и конверсия типов — операции тяжёлые. Каждый раз, когда выполняется обращение к переменной, её чтение или запись, производится проверка типа.
  • Язык, обладающей подобной гибкостью, сложно оптимизировать. Причина, по которой другие языки настолько быстрее Python, заключается в том, что они идут на те или иные компромиссы, выбирая между гибкостью и производительностью.
  • Проект Cython объединяет Python и статическую типизацию, что, например, как показано в этом материале, приводит к 84-кратному росту производительности в сравнении с применением обычного Python. Обратите внимание на этот проект, если вам нужна скорость.

Итоги


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

Приложения, написанные на Python, можно оптимизировать, используя возможности по асинхронному выполнению кода, инструменты профилирования, и — правильно подбирая интерпретатор. Так, для оптимизации скорости работы приложений, время запуска которых неважно, а производительность которых может выиграть от использования JIT-компилятора, рассмотрите возможность использования PyPy. Если вам нужна максимальная производительность и вы готовы к ограничениям статической типизации — взгляните на Cython.

Уважаемые читатели! Как вы решаете проблемы невысокой производительности Python?

Что нужно запомнить программисту, переходящему на Python / Habr

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

Однако в какой-то момент перл исчерпал себя и я решил заняться питоном, сначала просто делал что-то и разбирался с тем, что нужно для данной задачи, а потом понял, что нужны какие-то систематизированные знания и прочитал несколько книг:


  • Билл Любанович «Простой Python. Современный стиль программирования»
  • Дэн Бейдер «Чистый Python. Тонкости программирования для профи»
  • Бретт Слаткин «Секреты Python: 59 рекомендаций по написанию эффективного кода»

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

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

Я заметил, что на собеседованиях по питону достаточно часто задают вопросы про вещи не имеющие отношения к реальной разработке, типа того, что может быть ключом словаря (или про то что означает x = yield y), ну чуваки, в реальной жизни ключом может быть только число или строка, в тех уникальных случаях когда это не так, можно почитать документацию и разобраться, зачем спрашивать такое? Чтобы найти чего собеседуемый не знает? Так в итоге все запомнят ответ именно на этот вопрос и это перестанет работать.

Актуальными я считаю питон версий выше 3.5 (про второй питон давно пора забыть) т.к. именно такая версия в стабильном дебиане, а значит во всех остальных местах более свежие версии )

Так как я вовсе не гуру питона, то надеюсь меня поправят в комментариях если я вдруг сморозил какую-то глупость.


Типизация

Питон динамически типизированный язык т.е. он проверяет соответствие типов в процессе выполнения, например:

cat type.py

a=5
b='5'
print(a+b)

выполняем:

python3 type.py
... TypeError: unsupported operand type(s) for +: 'int' and 'str'

Однако, если ваш проект дозрел до необходимости статической типизации, то питон предоставляет и такую возможность путём использования статического анализатора mypy:

mypy type.py
type.py:3: error: Unsupported operand types for + ("int" and "str")

Правда так ловятся не все ошибки:

cat type2.py

def greeting(name):
    return 'Hello ' + name

greeting(5)

mypy тут не ругнётся, а при выполнении случится ошибка, поэтому актуальные версии питона поддерживают специальный синтаксис для указания типов аргументов функций:

cat type3.py
def greeting(name: str) -> str:
    return 'Hello ' + name

greeting(5)

а теперь:

mypy type3.py
type3.py:4: error: Argument 1 to "greeting" has incompatible type "int"; expected "str"

Переменные и данные

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

x = 1
y = x
x = 2
print(y)

приводит к тому, что переменные x и y ссылаются на различные данные, а такой:

x = [1, 2, 3]
y = x
x[0] = 7
print(y)

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

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

>>> mystr = 'sss'
>>> newstr = mystr  # делаем ссылку на те же данные
>>> mystr[0] = 'a'
...
  TypeError: 'str' object does not support item assignment
>>> mystr = 'ssa'  # меняем исходную переменную
>>> newstr  # данные не изменились и доступны по второй ссылке
  'sss'

Кстати, о строках, из-за их иммутабельности конкатенация очень большого списка строк сложением или append’ом в цикле может быть не очень эффективной (зависит от рализации в конкретном компиляторе/версии), обычно для таких случаев рекомендуют использовать метод join, который ведёт себя немного неожиданно:

>>> str_list = ['ss', 'dd', 'gg']
>>> 'XXX'.join(str_list)
'ssXXXddXXXgg'
>>> str = 'hello'
>>> 'XXX'.join(str)
'hXXXeXXXlXXXlXXXo'

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

Так как переменные это ссылки, то вполне нормальным является желание сделать копию объекта, чтобы не ломать исходный объект, однако тут есть подводный камень — функция copy копирует только один уровень, что явно не то, что ожидается от функции с таким именем, поэтому используете deepcopy.

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


Область видимости

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

Например, такой код:

x = 7
print(id(x))

def func():
    print(id(x))
    return x

print(func())

Работает с одной глобальной переменной, а такой:

x = 7
print(id(x))

def func():
    x = 1
    print(id(x))
    return x

print(func())
print(x)

уже порождает локальную.
С моей точки зрения это не очень хорошо, по идее любое использование нелокальных переменных в функции это часть публичного интерфейса функции, её сигнатуры, а значит должно объявляться явно и видимо в начале функции. Также ключевые слова не очень информативны — global звучит как определение глобальной функции, а на самом деле означает use global.

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

if __name__ == '__main__':
    main()

такое условие сработает если файл будет вызван как скрипт, а не импортирован как модуль.


Аргументы функций

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

Но нужно понимать как осуществляется передача аргументов — т.к. в питоне все переменные это ссылки на данные, то можно догадаться, что передача осуществляется по ссылке, однако тут есть особенность — сама ссылка передаётся по значению т.е. вы можете модифицировать мутабельное значение по ссылке:

def add_element(mylist):
    mylist.append(3)

mylist = [1,2]
add_element(mylist)
print(mylist)

выполняем:

python3 arg_modify.py
[1, 2, 3]

однако нельзя затереть исходную ссылку в функции:

def try_del(mylist):
    mylist = []
    return mylist

mylist = [1,2]
try_del(mylist)
print(mylist)

исходная ссылка жива и работает:

python3 arg_kill.py
[1, 2]

Также для аргументов можно задавать значения по умолчанию, но с этим есть одна неочевидная вещь которую нужно запомнить — значения по умолчанию вычисляются один раз при определении функции, это не создаёт никаких проблем, если вы в качестве значения по умолчанию передаёте неизменяемые данные, а если передаются изменяемые данные или динамическое значение, то результат будем чуток неожиданным:

изменяемые данные:

cat arg_list.py

def func(arg = []):
    arg.append('x')
    return arg

print(func())
print(func())
print(func())

результат:

python3 arg_list.py
['x']
['x', 'x']
['x', 'x', 'x']

динамическое значение:

cat arg_now.py

from datetime import datetime

def func(arg = datetime.now()):
    return arg

print(func())
print(func())
print(func())

получаем:

python3 arg_now.py
2018-09-28 10:28:40.771879
2018-09-28 10:28:40.771879
2018-09-28 10:28:40.771879

ООП

ООП в питоне сделано весьма интересно (одни property чего стоят) и это большая тема, однако сапиенс знакомый с ООП вполне может нагуглить всё (или найти на хабре), что ему захочется, поэтому нет смысла повторяться, хотя стоит оговорить, что питон следует немного другой философии — считается, что программист умнее машины и не является вредителем (UPD: подробнее), поэтому в питоне по умолчанию нет привычных по другим языкам модификаторов доступа: private методы реализуются добавлением двойного подчёркивания (что в рантайме изменяет имя метода не позволяя случайно его использовать), а protected одним подчёркиванием (что не делает ничего, это просто соглашение об именовании).
Те кто скучает по привычному функционалу могут поискать попытки привнести в питон такие возможности, мне нагуглилась пара вариантов (lang, python-access), но я их не тестировал и не изучал.

Единственный минус стандартных классов — шаблонный код во всяких дандер методах, лично мне нравится библиотека attrs, она значительно более питоническая.
Стоит упомянуть, что так в питоне всё объекты, включая функции и классы, то классы можно создавать динамически (без использования eval) функцией type.
Также стоит почитать про метаклассы (на хабре) и дескрипторы (хабр).
Особенность, которую стоит запомнить — атрибуты класса и объекта это не одно и тоже, в случае неизменяемых атрибутов это не вызывает проблем так как атрибуты «затеняются» (shadowing) — создаются автоматически атрибуты объекта с таким же именем, а вот в случае изменяемых атрибутов можно получить не совсем то, что ожидалось:

cat class_attr.py
class MyClass:
    storage = [7,]
    def __init__(self, number):
        self.number = number

obj = MyClass(1)
obj2 = MyClass(2)

obj.number = 5
obj.storage.append(8)

print(obj2.storage, obj2.number)

получаем:

python3 class_attr.py
[7, 8] 2

как можно увидеть — изменяли obj, а storage изменился и в obj2 т.к. этот атрибут (в отличии от number) принадлежит не экземпляру, а классу.


Константы

Как и в случае с модификаторами доступа питон не пытается ограничить разработчика, поэтому задачать скалярную переменную защищённую от модификации стандартным способом нельзя, просто есть соглашение, что переменные с именем в верхнем регистре нужно считать константами.
С другой стороны в питоне есть неизменяемые структуры данных такие как tuple, поэтому если вы хотите сделать неизменяемой какую-то глобальную структуру вроде конфига и не хотите дополнительных зависимостей, то namedtuple, вполне хороший выбор, хотя он потребует немного больше усилий для описания типов, поэтому мне нравится альтернативная реализация неизменяемой структуры с dot-notation — Box (см. параметр frozen_box).
Ну а если вам хочется скалярных констант, то можно реализовать проверку доступа к ним на стадии «компиляции» т.е. проверки через mypy, пример и подробности.


.sort() vs sorted()

В питоне есть два способо сортировать список. Первый это метод .sort() который изменяет исходный список и ничего не возвращает (None) т.е. не получится сделать так:

my_list = my_list.sort()

Второй, это функция sorted() которая порождает новый список и умеет работать со всеми итерируемыми объектами. Кому хочется больше инфы стоит начать с SO.


Стандартная библиотека

Обычно стандартная библиотека питона включает отличные решения типовых проблем, однако стоит подходить критически, ибо хватает и странностей. Правда бывает и так, что то, что на первый взгляд кажется странным, в итоге оказывается наилучшим решением, просто нужно знать все условия (см. далее про range), но всё же есть и странности.

Например, идущий в комплекте модуль для модульного тестирования unittest не имеет никакого отношения к питону и попахивает джавой, поэтому, как говорит автор питона: «Eveybody is using py.test …». Хотя вполне интересный, пусть и не всегда подходящий модуль doctest идёт в стандартной поставке.

Идущий в поставке модуль urllib не имеет такого прекрасного интерфейса как стронний модуль requests.

Та же история с модулем для разбора параметров коммандной строки — идущий в комплекте argparse это демонстрация ООП головного мозга, а модуль docopt кажется просто шикарным решением — предельная самодокументируемость! Хотя, по слухам, несмотря на docopt и для click остаётся ниша.

С отладчиком также — как я понял идущий в комплекте pdb мало кто использует, альтернатив много, но похоже основная масса разработчиков используется ipdb, который, с моей точки зрения удобнее всего использовать через модуль-обёртку debug.
Она позволяет вместо import ipdb;ipdb.set_trace() просто написать import debug, также она добавляет модуль see для удобной инспекции объектов.

На замену стандартному модулю сериализации pickle делают dill, тут кстати стоит запомнить, что эти модули не подходят для обмена данными в внешними системами т.к. восстанавливать произвольные объекты полученные из неконтролируемого источника небезопасно, для таких случаев есть json (для REST) и gRPC (для RPC).

На замену стандартному модулю обработкти регулярных выражений re делают модуль regex со всякими дополнительными плюшками, вроде классов символов аля \p{Cyrillic}.
Кстати, что-то не попалось для питона весёлого отладчика для регексов похожего на перловый.

Вот другой пример — человек сделал свой модуль in-place, чтобы пофиксить кривизну и неполноту API стандартного модуля fileinput в части in place редактирования файлов.

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


Параллелизм и конкурентность

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

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

А если в ваших задачах много ожидания IO, то питон предоставляет массу вариантов на выбор, от тредов и gevent, до asyncio.
Все эти варианты выглядят вполне пригодными для использования (хотя треды значительно больше ресурсов требуют), но есть ощущение, что asyncio потихоньку выдавливает остальных, в том числе благодаря всяким плюшками типа uvloop.

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


Иные странности

В питоне a = a + b не всегда эквивалентно a += b:

a = [1]
a = a + (2,3)
TypeError: can only concatenate list (not "tuple") to list
a += (2,3)
a
[1, 2, 3]

За деталями отправляю на SO ибо пока не нашёл времени разобраться почему оно так, в смысле по каким причинам так сделали, вроде это опять про мутабельность.


Странности, которые не странности

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

Отдельная большая тема это округления (хотя это проблема общая практически для всех языков программирования), помимо того, что округление используется какое угодно кроме того, что все изучали в школьном курсе математики, так на это ещё накладываются проблемы преставления чисел с плавющей точкой, отсылаю к подробной статье.
Грубо говоря вместо привычного, по школьному курсу математики, округления по алгоритма half up используется алгоритм half to even, которые уменьшает вероятность искажений при статистическом анализе и поэтому рекомендуется стандартом IEEE 754.

Также я не мог понять почему -22//10=-3, а потом, другой добрый человек, указал, что это неизбежно следует из самого математического определения, по которому, остаток не может быть отрицательным, что и приводит к такому необычному поведению для отрицательных чисел.
ACHTUNG! Теперь это опять странность и я ничего не понимаю, см. сей тред.


Отладка регулярных выражений

А вот тут оказалось, что в мире питоне нет инструмента для интерактивной отладки регулярных выражений аналогичного прекрасному перловому модулю Regexp::Debugger (видеопрезентация), конечно есть куча онлайн-инструментов, есть какие-то виндовопроприетарные решения, но для меня это всё не то, возможно стоит использовать перловый инструмент, ибо питонные регэксы не особо отличаются от перловых, напишу инструкцию для невладеющих перловым инструментарием:

sudo apt install cpanminus
cpanm Regexp::Debugger
perl -I ~/perl5/lib/perl5/ -E "use Regexp::Debugger; 'ababc' =~ /(a|b) b+ c/x"

Думаю даже человек незнакомый с перлом поймёт где тут надо вписать строку, а где регулярное выражение, x это флаг аналогичный питонному re.VERBOSE.
Нажимаем s и шагаем по регулярному выражению, подробное описание доступных команд в документации.


Документация

В питоне есть функция help, которая позволяет получить справку по любой загруженной функции (берётся из её docstring’а), параметром передаётся имя функции:

$ python3                                                                                                                                        
>>> help(help)

но это не всегда удобный способ и часто удобнее использовать утилиту pydoc:

pydoc3 urllib.parse.urlparse

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

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

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