Python 2: основные конструкции и примеры

Раздел: Основы Python -> Примеры кода

Основные конструкции Python 2

Наиболее эффективный способ писать код на Python 2, готовый к переносу на Python 3 - применение директив из модуля __future__. Импорт print_function, division, absolute_import и unicode_literals делает поведение близким к Python 3.

from __future__ import print_function, division, absolute_import, unicode_literals
print("Hello, World!")  # функция
print(5/2)              # 2.5
print(5//2)             # 2

Python 2 примеры (примеры кода на python 2)

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

Частая ошибка - забыть импортировать division и получить целочисленное деление. Другая проблема - импорт unicode_literals может привести к конфликтам с библиотеками, ожидающими str. В таких случаях стоит использовать явные префиксы b для байтовых строк.

Как получить пользовательский ввод в Python 2?

Функция raw_input возвращает строку, а input пытается выполнить eval() введённого выражения. Для безопасного ввода следует использовать raw_input:

name = raw_input("Введите имя: ")
print "Привет,", name
age = int(raw_input("Сколько лет? "))

Ошибка: использование input вводит уязвимость к выполнению произвольного кода. Решение - всегда применять raw_input и преобразовывать к нужному типу.

Как использовать диапазон чисел без создания списка?

В Python 2 range возвращает список, что неэффективно при больших числах. Функция xrange возвращает итератор, экономя память:

for i in xrange(1000000):
    pass

Для совместимости с Python 3 можно импортировать range из __future__.

Забывчивость: если используется range в большом цикле, память быстро расходуется. Решение - замена на xrange.

Как обрабатывать строки в юникоде?

В Python 2 строки по умолчанию - байтовые. Для работы с Unicode используется префикс u:

s = u"Привет, мир!"
print s
b = s.encode('utf-8')
print b

При импорте unicode_literals все строки без префикса становятся Unicode.

Типичная ошибка - UnicodeDecodeError при смешении байтовых и Unicode строк. Решение: чётко разделять типы, использовать decode и encode.

Как перехватить исключение с сохранением объекта?

В Python 2 синтаксис except Exception, e связывает переменную e. Более новый стиль except Exception as e также работает в Python 2 (начиная с 2.6):

try:
    1/0
except ZeroDivisionError as e:
    print "Ошибка:", e

Вариант с запятой тоже допустим, но менее читаем.

Использование старого синтаксиса с запятой может привести к синтаксической ошибке в Python 3. Рекомендуется as.

Как определить класс старого стиля?

Классы без явного наследования от object считаются старыми (classic classes). Новые классы наследуют от object:

class OldStyle:
    pass

class NewStyle(object):
    pass

Новые классы поддерживают super, свойства, дескрипторы. Для совместимости с Python 3 рекомендуется всегда наследовать от object.

Если класс не наследует от object, его методы __getattribute__ и другие ведут себя иначе.

Как использовать итераторы map, filter, zip в Python 2?

Эти функции возвращают списки. Для ленивых вычислений используйте модуль itertools (imap, ifilter, izip):

from itertools import imap, ifilter, izip
data = [1,2,3,4]
result = list(imap(lambda x: x*2, data))

Также map(None, ...) использовалось для zip разной длины.

Замена map на imap в большом наборе данных экономит память, но не возвращает список.

Как открыть файл с указанием кодировки?

Модуль codecs предоставляет функцию open для работы с кодировками:

import codecs
with codecs.open('file.txt', 'w', encoding='utf-8') as f:
    f.write(u"Привет")
with codecs.open('file.txt', 'r', encoding='utf-8') as f:
    content = f.read()

В Python 3 используется встроенный open с параметром encoding.

Использование встроенного open без кодировки приводит к получению байтовой строки.

Как получить список ключей словаря в порядке вставки?

В Python 2.7 появился OrderedDict из модуля collections. Обычный словарь не гарантирует порядок (хотя в CPython 2.7 порядок совпадает с вставкой, но это деталь реализации).

from collections import OrderedDict
d = OrderedDict()
d['a'] = 1
d['b'] = 2
for k, v in d.items():
    print k, v

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

Как вывести отладочную информацию в stderr?

Используется sys.stderr.write или print>>sys.stderr:

import sys
print >> sys.stderr, "Ошибка: ..."
sys.stderr.write("Ошибка: ...\n")

В Python 3 print(..., file=sys.stderr).

Забыть про >> и использовать обычный print - сообщение уходит в stdout.

Все перечисленные примеры охватывают ключевые отличия Python 2 от более новых версий. Каждый вариант предназначен для решения определённой задачи: обеспечение совместимости, работа с вводом-выводом, обработка данных, определение классов. Знание этих конструкций необходимо при поддержке существующих проектов на Python 2.

Генератор чисел Фибоначчи

Пример
def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

f = fib()
for _ in xrange(10):
    print f.next(),
0 1 1 2 3 5 8 13 21 34

Работа с JSON (simplejson)

Пример
import simplejson as json
data = {'name': u'Иван', 'age': 30}
json_str = json.dumps(data, ensure_ascii=False)
print json_str
parsed = json.loads(json_str)
print parsed['name']

HTTP запрос через urllib2

Пример
import urllib2
req = urllib2.Request('http://httpbin.org/get')
response = urllib2.urlopen(req)
print response.read()[:100]

Обход файлов с os.walk

Пример
import os
for root, dirs, files in os.walk('/tmp'):
    for name in files:
        if name.endswith('.txt'):
            print os.path.join(root, name)

Использование threading

Пример
import threading, time
def worker():
    print "Поток запущен"
    time.sleep(1)
    print "Поток завершён"
threads = []
for i in range(3):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)
for t in threads:
    t.join()

Сортировка с operator.itemgetter

Пример
from operator import itemgetter
data = [('Вася', 25), ('Петя', 20), ('Аня', 30)]
sorted_data = sorted(data, key=itemgetter(1))
print sorted_data
[('Петя', 20), ('Вася', 25), ('Аня', 30)]

Работа с pickle

Пример
import pickle
obj = {'a': [1,2,3], 'b': 'hello'}
with open('data.pkl', 'wb') as f:
    pickle.dump(obj, f)
with open('data.pkl', 'rb') as f:
    loaded = pickle.load(f)
print loaded
{'a': [1, 2, 3], 'b': 'hello'}

Примеры кода на Python 2 - comments

En
Python 2 примеры (python)