Главная страница
Навигация по странице:

  • Работа с записями двоичных данных

  • Учебник Python 3.1. Учебник Python 3. Учебник Python 1 Материал из Викиучебника. Оглавление


    Скачать 1.85 Mb.
    НазваниеУчебник Python 1 Материал из Викиучебника. Оглавление
    АнкорУчебник Python 3.1.pdf
    Дата05.04.2017
    Размер1.85 Mb.
    Формат файлаpdf
    Имя файлаУчебник Python 3.1.pdf
    ТипУчебник
    #4516
    страница12 из 13
    1   ...   5   6   7   8   9   10   11   12   13
    Форматирование вывода
    Модуль reprlib предоставляет версию функции repr()
    , настроенную на сокращённый вывод больших и многократно вложенных контейнеров:
    >>>
    import
    reprlib
    >>>
    reprlib.
    repr
    (
    set
    (
    'supercalifragilisticexpialidocious'
    ))
    "set(['a', 'c', 'd', 'e', 'f', 'g', ...])"
    Модуль pprint предлагает более утончённый контроль над выводом встроенных и определённых пользователем объектов способом, подходящим для интерпретатора. Когда
    81

    Учебник Python 3.1: Материал из Викиучебника.
    результат не умещается на строке, умный pprint добавляет по необходимости разбивку на строки и отступы, помогающие выделить структуру данных:
    >>>
    import
    pprint
    >>>
    t
    =
    [[[[
    'чёрный'
    ,
    'бирюзовый'
    ]
    ,
    'белый'
    ,
    [
    'зелёный'
    ,
    'красный'
    ]]
    ,
    [[
    'пурпурный'
    ,
    'жёлтый'
    ]
    ,
    'голубой'
    ]]]
    >>>
    pprint pprint
    (t
    ,
    width
    =
    30
    )
    [[[[
    'чёрный'
    ,
    'бирюзовый'
    ]
    ,
    'белый'
    ,
    [
    'зелёный'
    ,
    'красный'
    ]]
    ,
    [[
    'пурпурный'
    ,
    'жёлтый'
    ]
    ,
    'голубой'
    ]]]
    Модуль textwrap форматирует абзацы текста под определённую ширину:
    >>>
    import
    textwrap
    >>>
    doc
    =
    """Метод wrap() аналогичен fill(), но он возвращает список строк, а не одну большую строку с признаками концов строк."""
    >>>
    print
    (
    textwrap
    .fill(doc
    ,
    width
    =
    40
    ))
    Метод wrap() аналогичен fill()
    ,
    но он возвращает список строк
    ,
    а не одну большую строку с признаками концов строк.
    Модуль locale дает доступ к базе данных форматов различных культурных сред.
    Например, параметр grouping функции format этого модуля позволяет использовать группировку цифр принятыми в данной культурной среде разделителями:
    >>>
    import
    locale
    >>>
    locale
    .setlocale(
    locale
    .LC_ALL
    ,
    'en_US.UTF8'
    )
    'en_US.UTF8'
    >>>
    conv
    =
    locale
    .localeconv()
    # получить отображение соглашений
    >>>
    x
    =
    1234567.8
    >>>
    locale
    .format(
    "%d"
    ,
    x
    ,
    grouping
    =
    True
    )
    '1,234,567'
    >>>
    locale
    .format(
    "%s%.*f"
    ,
    (conv[
    'currency_symbol'
    ]
    ,
    conv[
    'frac_digits'
    ]
    ,
    x)
    ,
    grouping
    =
    True
    )
    '$1,234,567.80'
    Работа с шаблонами
    Модуль string включает в себя гибкий класс
    Template
    , реализующий шаблоны с простым синтаксисом, доступным для редактирования конечными пользователями. Использование этого класса позволит пользователям настраивать приложения без изменений в них самих.
    Формат использует имена полей для подстановки, записываемых как знак доллара (
    $
    ) с последующим идентификатором, состоящим, как и имена в программах на Python, из букв, цифр и подчёркиваний
    [60]
    . Фигурные скобки вокруг идентификатора позволяют использовать алфавитно-цифровые символы сразу после поля подстановки, без дополнительных пробелов. Собственно знак доллара необходимо записывать сдвоенно:
    $$
    >>>
    from
    string
    import
    Template
    >>>
    t
    =
    Template(
    '${village}folk send $$10 to $cause.'
    )
    >>>
    t.substitute(village
    =
    'Nottingham'
    ,
    cause
    =
    'the ditch fund'
    )
    'Nottinghamfolk send $10 to the ditch fund.'
    Метод substitute()
    возбуждает
    KeyError в случае, когда значение для поля отсутствует в переданных параметрах. Для приложений вроде массовой персонализированной рассылки, часть данных может отсутствовать. В таком случае лучше использовать
    82

    Учебник Python 3.1: Материал из Викиучебника.
    метод safe_substitute()
    : он оставит разметку полей подстановки в случае отсутствия данных.
    [61]
    >>>
    t
    =
    Template(
    'Return the $item to $owner.'
    )
    >>>
    d
    =
    dict
    (item
    =
    'unladen swallow'
    )
    >>>
    t.substitute(d)
    Traceback (most recent call last):
    KeyError
    :
    'owner'
    >>>
    t.safe_substitute(d)
    'Return the unladen swallow to $owner.'
    Производные от
    Template классы могут переопределить разделитель. Например, утилита переименования файлов просмотрщика фотографий может использовать знаки процента в разметке полей подстановки: текущая дата, номер изображения по порядку, формат файла:
    >>>
    import
    time
    ,
    os
    .path
    >>>
    photofiles
    =
    [
    'img_1074.jpg'
    ,
    'img_1076.jpg'
    ,
    'img_1077.jpg'
    ]
    >>>
    class
    BatchRename(Template):
    ... delimiter
    =
    '%'
    >>>
    fmt
    =
    input
    (
    'Введите стиль переименования (%d - дата, %n - номер п/п, %f - формат): '
    )
    Введите стиль переименования (%d - дата
    ,
    %n - номер п/п
    ,
    %f - формат): Ashley_%n
    %f
    >>>
    t
    =
    BatchRename(fmt)
    >>>
    date
    =
    time
    .strftime(
    '%d%b%y'
    )
    >>>
    for
    i
    ,
    filename
    in
    enumerate
    (photofiles):
    ... base
    ,
    ext
    =
    os
    .path.splitext(filename)
    ... newname
    =
    t.substitute(d
    =
    date
    ,
    n
    =
    i
    ,
    f
    =
    ext)
    print
    (
    '{0} --> {1}'
    .format(filename
    ,
    newname))
    img_1074.jpg --
    >
    Ashley_0.jpg img_1076.jpg --
    >
    Ashley_1.jpg img_1077.jpg --
    >
    Ashley_2.jpg
    Другое приложение для использования шаблонов - отделение логики от деталей реализации различных выходных форматов. Это даёт возможность строить шаблоны для
    XML-файлов, текстовых отчётов и веб-отчётов на HTML.
    Работа с записями двоичных данных
    Модуль struct предлагает функции pack()
    и unpack()
    для работы с форматами двоичных записей переменной длины. Следующий пример показывает как можно получить заголовочную информацию из ZIP-файла без использования модуля zipfile
    Коды "H"
    и "I"
    представляют двух- и четырехбайтовых беззнаковых числа соответственно.
    Код "<"
    обозначает, что числа стандартного размера и байты записаны в порядке «сначала младший» (little-endian):
    import
    struct data
    =
    open
    (
    'myfile.zip'
    ,
    'rb'
    ).read()
    start
    =
    0
    for
    i
    in
    range
    (
    3
    ):
    # показать первые три заголовка
    start +
    =
    14
    fields
    =
    struct
    .unpack(
    ',
    data[start:start+
    16
    ])
    crc32
    ,
    comp_size
    ,
    uncomp_size
    ,
    filenamesize
    ,
    extra_size
    =
    fields
    83

    Учебник Python 3.1: Материал из Викиучебника.
    start +
    =
    16
    filename
    =
    data[start:start+filenamesize]
    start +
    =
    filenamesize extra
    =
    data[start:start+extra_size]
    print
    (filename
    ,
    hex
    (crc32)
    ,
    comp_size
    ,
    uncomp_size)
    start +
    =
    extra_size + comp_size
    # пропустить до следующего заголовка
    Многопоточность
    Потоки (threads) могут использоваться для разделения задач, которые могут выполняться по времени независимо от друг от друга. Разделение на потоки может применяться для улучшения времени отклика приложений, ведущих диалог с пользователем пока другие задачи выполняются в фоновом режиме. Похожая ситуация с произведением ввода-вывода одновременно с вычислениями в другом потоке.
    Следующий пример показывает, как высокоуровневый модуль threading может выполнять фоновые задачи, продолжая выполнение основной программы:
    import
    threading
    ,
    zipfile
    class
    AsyncZip(
    threading
    .Thread):
    def
    __init__
    (
    self
    ,
    infile
    ,
    outfile):
    threading
    .Thread.
    __init__
    (
    self
    )
    self
    .infile
    =
    infile self
    .outfile
    =
    outfile
    def
    run(
    self
    ):
    f
    =
    zipfile
    .ZipFile(
    self
    .outfile
    ,
    'w'
    ,
    zipfile
    .ZIP_DEFLATED)
    f.write(
    self
    .infile)
    f.close()
    print
    (
    'Завершён фоновый zip для:'
    ,
    self
    .infile)
    background
    =
    AsyncZip(
    'mydata.txt'
    ,
    'myarchive.zip'
    )
    background.start()
    print
    (
    'Главная программа на переднем плане.'
    )
    background.join()
    # Ждём завершения фоновой задачи
    print
    (
    'Главная программа дождалась завершения фоновой задачи.'
    )
    Основной трудностью многопоточных приложений является координирование потоков, разделяющих общие данные или другие ресурсы. В помощь этому модуль threading предлагает целый ряд простых средств: замки́, события, переменные условий, семафоры и другие.
    Несмотря на достаточную мощь представленных средств даже небольшие погрешности в дизайне многопоточного приложения могут вызвать трудноповторимые проблемы. Таким образом, рекомендуемым подходом к координированию задач является централизация доступа к некоторому ресурсу в одном потоке и использование модуля queue для направления запросов из других потоков. Приложения, использующие Queue-объекты для межпотоковой связи и координирования, легче проектировать, сопровождать исходный код, они более надёжны.
    Запись в журнал
    Модуль logging предлагает богатую возможностями и гибкую систему ведения журнала. В простейшем случае сообщения отправляются на стандартный вывод ошибок - sys.stderr
    :
    import
    logging
    84

    Учебник Python 3.1: Материал из Викиучебника.
    logging
    .debug(
    'Отладочная информация'
    )
    logging
    .info(
    'Для информации'
    )
    logging
    .warning(
    'Предупреждение: файл %s не найден'
    ,
    'server.conf'
    )
    logging
    .error(
    'Произошла ошибка!'
    )
    logging
    .critical(
    'Критическая ошибка - выход'
    )
    Результат выполнения этого примера:
    WARNING:root:Предупреждение: файл server.conf не найден
    ERROR:root:Произошла ошибка!
    CRITICAL:root:Критическая ошибка - выход
    Без дополнительной настройки информационные и отладочные сообщения подавляются, а вывод направляется в sys.stderr
    . Другие варианты вывода: отправка сообщений по электронной почте, дейтаграммами, сокеты, на HTTP сервер. Другие фильтры могут выбирать различные варианты доставки в зависимости от приоритета: DEBUG, INFO, WARNING,ERROR или CRITICAL.
    Система записи в журнал может быть сконфигурирована напрямую из Python.
    Конфигурация также может быть загружена из конфигурационного файла и не требовать изменений в коде приложения.
    Слабые ссылки
    Python имеет автоматическое управление памятью: подсчёт ссылок для большинства объектов и сборка мусора для удаления циклов. Память освобождается сразу после того, как была удалена последняя ссылка на объект.
    Этот подход отлично работает для большинства приложений, но иногда возникает необходимость вести учёт объектов только когда они используются где-нибудь ещё. К сожалению, само слежение за объектами уже создает ссылку и тем самым объекты остаются в памяти. Модуль weakref
    (от англ. weak reference - слабая ссылка) даёт средство для учёта объектов без создания ссылок на них. Когда объект больше не нужен, он автоматически удаляется из таблицы слабых ссылок и производится обратный вызов weakref
    -объектов. Типичное применение модуля - кэширование объектов, которые затратно воспроизвести снова.
    >>>
    import
    weakref
    ,
    gc
    >>>
    class
    A:
    def
    __init__
    (
    self
    ,
    value):
    self
    .value
    =
    value
    def
    __repr__
    (
    self
    ):
    return
    str
    (
    self
    .value)
    >>>
    a
    =
    A(
    10
    )
    # создаёт ссылку
    >>>
    d
    =
    weakref
    .WeakValueDictionary()
    # словарь, использующий слабые ссылки
    >>>
    d[
    'primary'
    ]
    =
    a
    # не создаёт ссылки
    >>>
    d[
    'primary'
    ]
    # достать объект, если он все ещё "жив"
    10
    >>>
    del
    a
    # удалить одну ссылку
    >>>
    gc
    .collect()
    # произвести сборку мусора
    0
    >>>
    d[
    'primary'
    ]
    # запись была автоматически удалена
    Traceback (most recent call last):
    File
    ""
    ,
    line
    1
    ,
    in
    <
    module
    >
    d[
    'primary'
    ]
    File
    "C:/python31/lib/weakref.py"
    ,
    line
    46
    ,
    in
    __getitem__
    o
    =
    self
    .data[key]()
    85

    Учебник Python 3.1: Материал из Викиучебника.
    KeyError
    :
    'primary'
    Работа со списками
    В Python список может заменить многие структуры данных. Однако иногда необходимы альтернативные реализации, которые имеют другое компромиссное решение в отношении производительности.
    Модуль array
    (массив) предоставляет объект array
    , отличающийся от списка лишь возможностью более компактно хранить однородные данные. Следующий пример показывает массив чисел, хранимый в виде двухбайтных беззнаковых чисел (типокод "
    H
    "), а не в обычном списке, где каждый элемент типа int обычно занимает 16 байт:
    >>>
    from
    array
    import
    array
    >>>
    a
    =
    array
    (
    'H'
    ,
    [
    4000
    ,
    10
    ,
    700
    ,
    22222
    ])
    >>>
    sum
    (a)
    26932
    >>>
    a[
    1
    :
    3
    ]
    array
    (
    'H'
    ,
    [
    10
    ,
    700
    ])
    Модуль collections
    (коллекции) среди прочего предоставляет объект deque
    (дек, двухсторонняя очередь). Объекты этого типа имеют более быстрые операции вставки
    (append) и извлечения (pop) слева, но более медленный поиск внутренних элементов. Эти объекты хорошо подходят для реализации очередей и деревьев поиска в ширину:
    >>>
    from
    collections
    import
    deque
    >>>
    d
    =
    deque([
    "задача1"
    ,
    "задача2"
    ,
    "задача3"
    ])
    >>>
    d.append(
    "task4"
    )
    >>>
    print
    (
    "Обрабатывается"
    ,
    d.popleft())
    Обрабатывается задача
    1
    unsearched
    =
    deque([starting_node])
    def
    breadth_first_search(unsearched):
    node
    =
    unsearched.popleft()
    for
    m
    in
    gen_moves(node):
    if
    is_goal(m):
    return
    m unsearched.append(m)
    В дополнение к альтернативным реализациям списков библиотека также предлагает средства вроде модуля bisect с функциями для манипуляции отсортированными списками:
    >>>
    import
    bisect
    >>>
    scores
    =
    [(
    100
    ,
    'perl'
    )
    ,
    (
    200
    ,
    'tcl'
    )
    ,
    (
    400
    ,
    'lua'
    )
    ,
    (
    500
    ,
    'python'
    )]
    >>>
    bisect
    .insort(scores
    ,
    (
    300
    ,
    'ruby'
    ))
    # вставка значения в отсортированный
    список
    >>>
    scores
    [(
    100
    ,
    'perl'
    )
    ,
    (
    200
    ,
    'tcl'
    )
    ,
    (
    300
    ,
    'ruby'
    )
    ,
    (
    400
    ,
    'lua'
    )
    ,
    (
    500
    ,
    'python'
    )]
    Модуль heapq имеет функции для реализации кучи, основанной на обычных списках.
    Элемент с наименьшим значением всегда находится в позиции с индексом 0. Это свойство может с успехом быть задействовано в приложениях, где особенно частый доступ необходим к наименьшему элементу, но полную сортировку проводить накладно.
    >>>
    from
    heapq
    import
    heapify
    ,
    heappop
    ,
    heappush
    >>>
    data
    =
    [
    1
    ,
    3
    ,
    5
    ,
    7
    ,
    9
    ,
    2
    ,
    4
    ,
    6
    ,
    8
    ,
    0
    ]
    >>>
    heapify(data)
    # сделать из списка кучу
    >>>
    heappush(data
    ,
    -
    5
    )
    # добавить новый элемент
    >>>
    [heappop(data)
    for
    i
    in
    range
    (
    3
    )]
    # извлечь три наименьших значения
    [-
    5
    ,
    0
    ,
    1
    ]
    86

    Учебник Python 3.1: Материал из Викиучебника.
    Десятичная арифметика чисел с плавающей запятой
    Модуль decimal предоставляет тип данных
    Decimal для десятичной арифметики с плавающей запятой. В сравнении со встроенной двоичной арифметикой, новый класс особенно полезен в финансовых приложениях и других случаях, требующих точного десятичного представления, управления точностью, округлением c соблюдением законодательных и нормативных требований, отслеживания количества значащих цифр или для приложений, от которых ожидается совпадение с результатами, проделанными "вручную".
    Например, вычисление 5%-ного налога на 70 копеечный телефонный счет даёт различные результаты при использовании десятичной и двоичной арифметик. Разница становится значащей при округлении до ближайшей копейки:
    >>>
    from
    decimal
    import
    *
    >>>
    Decimal(
    '0.70'
    ) * Decimal(
    '1.05'
    )
    Decimal(
    "0.7350"
    )
    >>>
    .70
    *
    1.05 0.73499999999999999
    Что дальше?
    Чтение этого учебника, возможно, усилило ваш интерес к применению Python, и вы жаждете использовать этот язык для решения конкретных задач. Где можно пополнить знания о Python?
    Этот учебник является частью набора документации Python. В этом наборе есть и другие документы.
    Сноски:
    1.

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

    В случае операционных систем UNIX, интерпретатор версии 3.1 по умолчанию устанавливается с исполняемым файлом, имеющим имя, отличное от python — дабы не иметь конфликтов с (возможно) установленным исполняемым файлом версии 2.6 3.

    (Прим. перев.) primary prompt — зд., основное приглашение: приглашение к вводу команды или нескольких команд (сценария);
    4.

    (Прим. перев.) сontinuation lines — зд., продолжающие строки (строки продолжения): строки, продолжающие текст команды (оператора, выражения), или раскрывающие внутреннее устройство внешнего оператора (команды, выражения), в последнем случае определяются дополнительным отступом от края — углублением в структуру;
    5.

    (Прим. перев.) secondary prompt — зд., вспомогательное приглашение: приглашение к продолжению ввода команды или набора команд (сценария) с использованиемпродолжающих строк;
    6.

    (Прим. перев.) Здесь и далее тексты некоторых исходных кодов также будут переведены в примечаниях (вместе с ключевыми словами, поэтому их нельзя будет
    87

    1   ...   5   6   7   8   9   10   11   12   13


    написать администратору сайта