Python

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

· прост в изучении;

· мега-универсальный;

· огромное разнообразие модулей и библиотек.

Я пользуюсь Python ежедневно — это неотъемлемая часть моей работы в качестве специалиста по исследованию данных. За время своей трудовой деятельности я открыл для себя несколько полезных хитростей и трюков.

В данной статье я постарался структурировать их в алфавитном порядке.

С большей частью всего этого я сам сталкивался или пользовался в работе. Что-то было найдено в документации стандартных библиотек Python. А некоторые вещи нашлись в PyPi.

Еще должен отметить то, что четыре или пять приемов я встретил на awesome-python.com. Это специально отобранный список сотен самых интересных инструментов и модулей для Python. Очень даже вдохновляет при просмотре!

all или any

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

Часто можно слышать, как Python в шутку называют ‘исполняемым псевдокодом’. А ведь и правда: если написать код вот так, то поспорить с этим будет достаточно сложно:

x = [True, True, False]
if any(x):
    print("At least one True")
if all(x):
    print("Not one False")
if any(x) and not all(x):
    print("At least one True and one False")

bashplotlib

Хотите построить графики в консоли?

$ pip install bashplotlib

Теперь они у вас есть.

collections

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

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

from collections import OrderedDict, Counter
# Remembers the order the keys are added!
x = OrderedDict(a=1, b=2, c=3)
# Counts the frequency of each character
y = Counter("Hello World!")

dir

Интересовались ли вы когда-нибудь тем, как можно заглянуть внутрь Python объекта и увидеть все его атрибуты? Конечно же, да.

Из командной строки:

>>> dir()
>>> dir("Hello World")
>>> dir(dir)

Функция эта крайне полезна при запуске Python в интерактивном режиме или работе с динамическими объектами и модулями.

Подробнее можно почитать здесь.

эмодзи

Да, они самые.

$ pip install emoji

Не притворяйтесь, будто не попробуете повторить…

from emoji import emojize
print(emojize(":thumbs_up:"))

👍

импорт из __future__

Одно из следствий популярности Python — постоянная разработка следующих версий. Новые версии несут в себе новые функции, если, конечно, ваша версия не устаревшая.

Бояться здесь нечего. Модуль_future_ позволяет импортировать в Python функционал будущих версий. Без всяких преувеличений, перед вами — настоящее путешествие во времени или магия.

from __future__ import print_function
print("Hello World!")

Почему бы не попробовать импортировать фигурные скобки?

geopy

География бывает крайне загадочной средой для программистов (ха, вот так каламбур!). Но с модулем geopy все становится на удивление просто.

$ pip install geopy

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

Существует и другой полезный класс — distance. Он определяет расстояние между двумя точками в ваших любимых единицах измерения.

from geopy import GoogleV3
place = "221b Baker Street, London"
location = GoogleV3().geocode(place)
print(location.address)
print(location.location)

howdoi

Застряли на какой-то проблеме с кодом и не можете вспомнить нужное решение? Хотите зайти в StackOverflow, но не хотите выходить из терминала?

Тогда вам точно пригодится вот этот инструмент для командной строки.

$ pip install howdoi

Задайте ему любой вопрос, и он постарается выдать нужный ответ.

$ howdoi vertical align css
$ howdoi for loop in java
$ howdoi undo commits in git

Однако будьте внимательны: howdoi выдирает код из самых популярных ответов StackOverflow.Поэтому не всегда выдает самую полезную информацию…

$ howdoi exit vim

inspect

Модуль inspect идеален для понимания общего «закулисья» Python. А еще вы можете вызывать его методы!

Пример кода ниже использует inspect.getsource() для вывода собственного номера строки. А inspect.getmodule() используется для печати модуля, в котором он был определен.

Последняя строка кода выводит собственный номер строки.

import inspect
print(inspect.getsource(inspect.getsource))
print(inspect.getmodule(inspect.getmodule))
print(inspect.currentframe().f_lineno)

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

Jedi

Jedi — это библиотека для autocomplete и анализа кода. С ней процесс написания кода станет быстрее и эффективнее.

Ну, а если вы не разрабатываете собственную среду IDE, то вы можете использовать Jedi в качестве плагина редактирования. К счастью, все это уже доступно для скачивания!

Быть может, вы уже пользуетесь Jedi. Проект IPython использует функционал Jedi для автодополнения кода.

**kwargs

Изучение любого языка складывается из ряда этапов. В Python одним из таких этапов можно назвать понимание загадочного синтаксиса **kwargs.

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

Ключи словаря — это имена аргумента, а значения превращаются в значения, передаваемые в функцию. Вам даже не придется называть ее kwargs!

dictionary = {"a": 1, "b": 2}
def someFunction(a, b):
    print(a + b)
    return
# these do the same thing:
someFunction(**dictionary)
someFunction(a=1, b=2)

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

Генераторы списков

Моя одна из любимых вещей в программировании на Python — это генератор списков.

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

Подробнее почитать про использование генераторов списков можно здесь.

numbers = [1,2,3,4,5,6,7]
evens = [x for x in numbers if x % 2 is 0]
odds = [y for y in numbers if y not in evens]
cities = ['London', 'Dublin', 'Oslo']
def visit(city):
    print("Welcome to "+city)
for city in cities:
    visit(city)

map

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

x = [1, 2, 3]
y = map(lambda x : x + 1 , x)
# prints out [2,3,4]
print(list(y))

В примере выше map()применяет простую лямбда-функцию к каждому элементу вx. Она возвращает объект map, который можно преобразовать в итерированный объект (например, в список или кортеж).

newspaper3k

Если вы никогда не видели этого ранее, то готовьтесь к тотальному выносу мозга с модулем newspaper в Python.

Он может доставать новостные статьи и связанные с ними мета-данные из ряда ведущих международных изданий. Извлекать можно картинки, текст и имена авторов.

В модуле присутствует даже встроенный функционал обработки естественного языка (NLP).

Если вдруг в своем следующем проекте вы подумывали прибегнуть к помощи BeautifulSoup или любой другой DIY webscraping-библиотеки, то не тратьте зря время и силы, и смело берите $ pip install newspaper3k .

Перезагрузка оператора

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

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

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

class Thing:
    def __init__(self, value):
        self.__value = value
    def __gt__(self, other):
        return self.__value > other.__value
    def __lt__(self, other):
        return self.__value < other.__value
something = Thing(100)
nothing = Thing(0)
# True
something > nothing
# False
something < nothing
# Error
something + nothing

pprint

Стандартная функцияprint в Python знает свое дело. Но попробуйте вывести на печать крупный и вложенный объект, и вас ждет сплошное разочарование.

Вот здесь-то и приходит на помощь модуль pretty-print из стандартной библиотеки. Он выводит сложно-структурированные объекты в удобочитаемом виде.

Настоящий must-have для любого Python-разработчика, имеющего дело с нетривиальными структурами данных.

import requests
import pprint
url = 'https://randomuser.me/api/?results=1'
users = requests.get(url).json()
pprint.pprint(users)

Очередь

В Python предусмотрена поддержка мультизадачности. Это делается через модуль стандартной библиотеки Queue.

Этот модуль реализует работу со структурой данных «очередь». Такая структура позволяет добавлять и извлекать записи по определенному правилу.

В очереди «Первым пришел — первым ушел» (или FIFO) можно извлекать объекты в порядке их добавления. Метод «Последним пришел — первым ушел» сначала открывает доступ к недавно добавленным объектам.

И, наконец, очередь с приоритетом позволяет извлекать объекты в соответствие с порядком их сортировки.

Вот пример использования очередей для многопоточного программирования в Python.

__repr__

При определении класса или объекта в Python лучше снабжать его «официальным» представлением в виде строки. Например:

>>> file = open('file.txt', 'r')
>>> print(file)
<open file 'file.txt', mode 'r' at 0x10d30aaf0>

Это значительно упрощает отладку кода. Добавляйте синтаксис к определению класса следующим образом:

class someClass:
    def __repr__(self):
        return "<some description here>"
someInstance = someClass()
# prints <some description here>
print(someInstance)

sh

Python — это отличный скриптовый язык. Иногда использование стандартных библиотек os и subprocess становится настоящей головной болью.

А библиотека sh является отличной альтернативой.

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

from sh import *
sh.pwd()
sh.mkdir('new_folder')
sh.touch('new_file.txt')
sh.whoami()
sh.echo('This is great!')

Подсказки типа

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

Такой прием сокращает время разработки. Однако есть и более страшные вещи, чем ошибка при выполнении, вызванная простой проблемой ввода.

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

def addTwo(x : Int) -> Int:
    return x + 2

А также задавать псевдонимы типа:

from typing import List
Vector = List[float]
Matrix = List[Vector]
def addMatrix(a : Matrix, b : Matrix) -> Matrix:
  result = []
  for i,row in enumerate(a):
    result_row =[]
    for j, col in enumerate(row):
      result_row += [a[i][j] + b[i][j]]
    result += [result_row]
  return result
x = [[1.0, 0.0], [0.0, 1.0]]
y = [[2.0, 1.0], [0.0, -2.0]]
z = addMatrix(x, y)

Аннотации типа (хоть они и не обязательны) могут облегчить читаемость кода.

К тому же, в них предусмотрены средства проверки типов, чтобы успевать «отлавливать» пресловутые TypeErrors до момента выполнения. Очень дельная штука, особенно при работе над крупными и сложными проектами!

uuid

Простой и быстрый способ генерирования Универсальных уникальных идентификаторов (или UUIDs) — это использование модуля uuid из стандартной библиотеки Python.

import uuid
user_id = uuid.uuid4()
print(user_id)

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

К слову сказать, сгенерировать можно свыше 2¹²² UUID. Это более пяти ундециллионов (или 5,000,000,000,000,000,000,000,000,000,000,000,000).

Вероятность повтора комбинации в данном диапазоне ничтожно мала. Даже при триллионе UUID вероятность появления дубля существующего значения намного меньше, чем один к миллиарду.

Очень круто для двух строчек кода.

Виртуальные среды

Эта часть — моя самая любимая в Python.

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

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

python -m venv my-project
source my-project/bin/activate
pip install all-the-modules

Теперь у вас есть автономные версии и установщики Python, работающие на одной машине. Проблема решена!

wikipedia

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

Модуль wikipedia делает доступ к этому API до безобразия удобным.

import wikipedia
result = wikipedia.page('freeCodeCamp')
print(result.summary)
for link in result.links:
    print(link)

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

xkcd

Юмор — это визитная карточка языка Python. В конце концов, его и назвали в честь британского комедийного скетча Монти Пайтон: Летающий цирк. Львиная доля официальной документации по Python имеет отсылки к самым известным скетчам шоу.

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

import antigravity

Никогда не меняйся, Python. Оставайся таким же.

YAML

YAML расшифровывается как YAML — не язык разметки. Это язык форматирования данных, который является расширенной версией JSON.

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

Модуль РyYAML позволяет использовать YAML вместе с Python. Установите его вот так:

$ pip install pyyaml

А затем импортируйте в свои проекты:

import yaml

PyYAML позволяет хранить объекты Python всех типов данных и экземпляры любых пользовательских классов.

zip

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

keys = ['a', 'b', 'c']
vals = [1, 2, 3]
zipped = dict(zip(keys, vals))

Встроенная функция zip() берет несколько итерируемых объектов и возвращает список кортежей. Каждый кортеж группирует элементы входных объектов по их позиционному индексу.

Вы можете даже «распаковать» объекты, вызвав *zip().

Перевод статьи Peter Gleeson: An A-Z of useful Python tricks