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

  • СОВЕТ Для установки пакетов Python могут использоваться менеджеры пакетов, исполняемые файлы Windows или специализированные средства Python, такие как pip125.5. sys.path

  • 25.6. Итоги В этой главе рассматриваются модули и пакеты. Модуль представляет собой файл Python. Пакет представляет собой каталог, в котором при- 25.7. Упражнения 249

  • 26.3. Типичная структура

  • 26.5. Строка документации

  • 26.7. Метаданные и глобальные переменные

  • Как устроен Python. Как устроен Python. Харрисон. Харрисон Мэтт


    Скачать 5.41 Mb.
    НазваниеХаррисон Мэтт
    АнкорКак устроен Python
    Дата05.02.2022
    Размер5.41 Mb.
    Формат файлаpdf
    Имя файлаКак устроен Python. Харрисон.pdf
    ТипДокументы
    #352210
    страница20 из 21
    1   ...   13   14   15   16   17   18   19   20   21
    СОВЕТ
    Оставьте переменную
    PYTHONPATH
    пустой, если только у вас нет веских при- чин для ее изменения. В этом разделе показано, что может произойти при ее изменении. Последствия могут сбить с толку других разработчиков, пытаю- щихся отладить ваш код, если они забудут о том, что переменная
    PYTHONPATH
    была изменена.
    Если вы включили код в файл
    /home/test/a/plot.py
    , но работали из каталога
    /home/test/b/
    , использование
    PYTHONPATH
    предоставит доступ к этому коду.
    В противном случае, если файл plot.py не был установлен системными средствами или средствами Python, попытка его импортирования при- ведет к ошибке
    ImportError
    :
    >>> import plot
    Traceback (most recent call last):

    25.5. sys.path
    247
    File "", line 1, in
    ImportError: No module named plot
    Если вы запустите Python с присваиванием значения переменной
    PYTHONPATH
    , она укажет Python, где нужно искать библиотеки:
    $ PYTHONPATH=/home/test/a python3
    Python 3.6.0 (default, Dec 24 2016, 08:01:42)
    >>> import plot
    >>> plot.histogram()
    СОВЕТ
    Для установки пакетов Python могут использоваться менеджеры пакетов, исполняемые файлы Windows или специализированные средства Python, такие как pip
    1
    25.5. sys.path
    У модуля sys имеется атрибут path со списком каталогов, в которых
    Python ищет библиотеки. Просмотрев sys.path
    , вы увидите все просмо- тренные каталоги:
    >>> import sys
    >>> sys.path
    ['',
    '/usr/lib/python35.zip',
    '/usr/lib/python3.6',
    '/usr/lib/python3.6/plat-darwin',
    '/usr/lib/python3.6/lib-dynload',
    '/usr/local/lib/python3.6/site-packages']
    СОВЕТ
    Если вы сталкиваетесь с ошибкой вида
    ImportError: No module named plot,
    обратитесь к переменной sys.path и посмотрите, присутствует ли в ней каталог, в котором находится файл foo.py
    (если это модуль). Если plot
    1
    https://pip.pypa.io/

    248
    Глава 25. Библиотеки: пакеты и модули является пакетом, то каталог plot/
    должен находиться в одном из каталогов из sys.path
    :
    >>> import plot
    Traceback (most recent call last):
    File "", line 1, in
    ImportError: No module named plot
    >>> sys.path.append('/home/test/a')
    >>> import plot
    >>> plot.histogram()
    Также можно включить этот каталог в
    PYTHONPATH
    из командной строки, ис- пользуемой для запуска Python.
    Еще раз подчеркнем, что обычно задавать вручную sys.path или
    PYTHONPATH
    не нужно. В нормальной ситуации вы устанавливаете библиотеки, а про- грамма установки размещает их в правильном каталоге.
    СОВЕТ
    Если вы хотите узнать местонахождение библиотеки в файловой системе, проверьте атрибут
    __file__
    :
    >>> import json
    >>> json.__file__
    '/usr/lib/python3.6/json/__init__.py'
    Этот способ работает только с библиотеками, реализованными на Python.
    Модуль sys не реализован на Python, поэтому эта попытка завершается неудачей:
    >>> import sys
    >>> sys.__file__
    Traceback (most recent call last):
    AttributeError: module 'sys' has no attribute '__file__'
    25.6. Итоги
    В этой главе рассматриваются модули и пакеты. Модуль представляет собой файл Python. Пакет представляет собой каталог, в котором при-

    25.7. Упражнения
    249
    сутствует файл с именем
    __init__.py
    . Пакет также может содержать другие модули и пакеты.
    Существует список путей, который определяет, к каким каталогам об- ращается Python для импортирования библиотек. Этот список хранится в sys.path
    . Проверив значение этой переменной, вы узнаете, какие ката- логи просматривает Python. Вы также можете обновить этот список при помощи переменной
    PYTHONPATH
    или же внести изменения напрямую. Но обычно вместо изменения этой переменной вы используете специализи- рованные средства установки пакетов, например pip.
    25.7. Упражнения
    1. Создайте модуль begin.py
    , который содержит функцию с именем prime
    . Функция prime должна получать число и возвращать логиче- ский признак того, является ли число простым (то есть делится ли оно только на 1 и на себя). Перейдите в другой каталог, запустите
    Python и выполните команду from begin import prime
    Попытка должна завершиться неудачей. Обновите переменную sys.
    path
    , чтобы вы могли импортировать функцию из модуля. Затем присвойте значение
    PYTHONPATH
    2. Создайте пакет utils
    . В файле
    __init__.py разместите код prime из предыдущего примера. Перейдите в другой каталог в терминале, запустите Python и выполните команду from utils import prime
    Попытка должна завершиться неудачей. Обновите переменную sys.path
    , чтобы вы могли импортировать функцию из пакета. Затем присвойте значение
    PYTHONPATH

    26
    Полноценный пример
    В этой главе вы узнаете, как организовать код в сценарии. В ней при- водится исходный код упрощенной реализации команды UNIX cat
    Команда cat читает имена файлов из командной строки и выводит их содержимое на экран. Предусмотрены различные параметры для вы- полнения таких операций, как добавление нумерации. Этот сценарий показывает, как организован код в типичном файле Python.
    26.1. cat.py
    Ниже приведена реализация команды UNIX cat на языке Python. Вклю- чен параметр для добавления нумерации строк (
    --number
    ), но другие параметры cat не поддерживаются. Сохраните код в файле с именем cat.py
    :
    #!/usr/bin/env python3
    r"""Простая реализация команды unix ``cat``.
    Поддерживается только параметр ``--number``.
    Пример демонстрирует структуру файла и полезные приемы программирования на Python.
    Строка документации в тройных кавычках для всего модуля
    (этот файл). Если импортировать этот модуль и выполнить команду ``help(cat)``, вы сможете убедиться в этом.
    Строка документации также содержит ``документирующий тест``,

    26.1. cat.py
    251
    который служит примером программного использования кода.
    Модуль ``doctest`` может выполнить эту строку документации и проверить ее правильность по выходным данным.
    >>> import io
    >>> fin = io.StringIO(\
    ... 'hello\nworld\n')
    >>> fout = io.StringIO()
    >>> cat = Catter([fin],
    ... show_numbers=True)
    >>> cat.run(fout)
    >>> print(fout.getvalue())
    1 hello
    2 world
    """
    import argparse import logging import sys
    __version__ = '0.0.1'
    logging.basicConfig(
    level=logging.DEBUG)
    class Catter(object):
    """
    Класс для конкатенации файлов в стандартном выводе
    Строка документации класса,
    выводится командой ``help(cat.Catter)``
    """
    def __init__(self, files,
    show_numbers=False):
    self.files = files self.show_numbers = show_numbers def run(self, fout):
    # Использовать 6 пробелов для чисел
    # с выравниванием по правому краю fmt = '{0:>6} {1}'

    252
    Глава 26. Полноценный пример for fin in self.files:
    logging.debug('catting {0}'.format(fin))
    for count, line in enumerate(fin, 1):
    if self.show_numbers:
    fout.write(fmt.format(
    count, line))
    else:
    fout.write(line)
    def main(args):
    """
    Логика выполнения cat с аргументами """
    parser = argparse.ArgumentParser(
    description='Concatenate FILE(s), or '
    'standard input, to standard output')
    parser.add_argument('--version',
    action='version', version=__version__)
    parser.add_argument('-n', '--number',
    action='store_true',
    help='number all output lines')
    parser.add_argument('files', nargs='*',
    type=argparse.FileType('r'),
    default=[sys.stdin], metavar='FILE')
    parser.add_argument('--run-tests',
    action='store_true',
    help='run module tests')
    args = parser.parse_args(args)
    if args.run_tests:
    import doctest doctest.testmod()
    else:
    cat = Catter(args.files, args.number)
    cat.run(sys.stdout)
    logging.debug('done catting')
    if __name__ == '__main__':
    main(sys.argv[1:])
    Если вам не хочется вводить весь этот код вручную, загрузите его копию из интернета
    1 1
    https://github.com/mattharrison/IllustratedPy3/

    26.2. Что делает этот код?
    253
    26.2. Что делает этот код?
    Этот код осуществляет эхо-вывод содержимого файла (возможно, с ну- мерацией строк) на терминал в системах Windows и
    UNIX:
    $ python3 cat.py -n README.md
    1 # IllustratedPy3 2
    3 If you have questions or concerns, click on Issues above.
    Если вы запустите этот код с ключом
    -h
    , он выведет всю справочную документацию по аргументам командной строки:
    $ python3 cat.py -h usage: cat.py [-h] [--version] [-n] [--run-tests] [FILE [FILE ...]]
    Concatenate FILE(s), or standard input, to standard output positional arguments:
    FILE
    optional arguments:
    -h, --help show this help message and exit
    --version show program's version number and exit
    -n, --number number all output lines
    --run-tests run module tests
    Функциональность разбора командной строки реализована в функции main и обеспечивается модулем argparse из стандартной библиотеки.
    Модуль argparse берет на себя всю работу по разбору аргументов.
    Если вы хотите узнать, что делает модуль argparse
    , обратитесь к до- кументации в интернете или воспользуйтесь функцией help
    . Основная идея заключается в том, что вы создаете экземпляр класса
    ArgumentParser и вызываете
    .add_argument для каждого параметра командной строки. Вы указываете параметры командной строки, сообщаете, какое действие не- обходимо для них выполнить (по умолчанию это сохранение значения, следующего за параметром), и предоставляете справочную документа- цию. После добавления аргументов вызывается метод
    .parse_args для аргументов командной строки (которые берутся из sys.argv
    ). Резуль- тат
    .parse_args представляет собой объект, к которому присоединены

    254
    Глава 26. Полноценный пример атрибуты, имена которых определяются именами параметров. В данном случае это будут атрибуты
    .files и
    .number
    ПРИМЕЧАНИЕ
    Вы также можете воспользоваться REPL для получения информации о модуле и просмотра документации, входящей в его поставку. Помните функцию help
    ? Передайте ей модуль, и она выведет строку документации уровня модуля.
    Если вы хотите просмотреть исходный код модуля, это тоже возможно.
    Помните функцию dir
    , которая выводит атрибуты объекта? Просмотрев информацию модуля argparse
    , вы увидите, что у него есть атрибут
    __file__
    Он указывает на местонахождение файла на компьютере:
    >>> import argparse
    >>> argparse.__file__
    '/usr/local/Cellar/python3/3.6.0/Frameworks/
    Python.framework/Versions/3.6/lib/python3.6/argparse.py'
    Так как код написан на Python (часть модулей написана на C), вы можете просмотреть файл с исходным кодом. К настоящему моменту вы уже сможете прочитать модуль и понять, что он должен делать.
    После разбора аргументов программа создает экземпляр
    Catter
    , опреде- ленный в коде, и вызывает для него метод
    .run
    Пример выглядит немного устрашающе, но весь использованный син- таксис рассматривался в книге. В оставшейся части этой главы рассма- тривается структура и другие аспекты этого кода.
    26.3. Типичная структура
    Основные компоненты модуля Python в порядке их следования:
    
    #!/usr/bin/env python3
    (если модуль также используется в качестве сценария);
    
    строка документации модуля;
    
    imports
    ;

    26.4. #!
    255
    
    метаданные и глобальные переменные;
    
    операции с журналом;
    
    реализация;
    
    if
    __name__
    ==
    '__main__':
    (если модуль также используется в каче- стве сценария);
    
    argparse
    ПРИМЕЧАНИЕ
    Этот список — не более чем рекомендация. Большинство элементов может следовать в произвольном порядке, и не все элементы должны присутство- вать в каждом файле. Например, не каждый файл должен быть исполняемым в качестве сценария командного интерпретатора.
    В своих файлах вы можете применять любую структуру, но ответственность за такое решение ложится на вас. Скорее всего, пользователи вашего кода будут недовольны (или будут выпускать исправления). Любой читатель предпочтет код, построенный по общепринятым правилам, так как он сможет быстро разобраться в его логике.
    26.4. #!
    Первая строка файла, используемого в качестве сценария, содержит по- следовательность символов
    #!/usr/bin/env python3
    . В операционных си- стемах семейства UNIX эта строка обрабатывается для определения того, как следует выполнять сценарий. Соответственно, эта строка включается только в те файлы, которые должны выполняться в качестве сценариев.
    В ней должна использоваться команда python
    3
    , так как команда python в большинстве систем относится к Python версии 2.
    ПРИМЕЧАНИЕ
    На платформе Windows строка
    #!
    игнорируется, поэтому ее включение безопасно. Вы найдете ее во многих библиотеках, популярных в системах
    Windows.

    256
    Глава 26. Полноценный пример
    ПРИМЕЧАНИЕ
    Вместо того чтобы жестко задавать конкретный путь к исполняемому файлу
    Python,
    /usr/bin/env выбирает первый исполняемый файл python3
    из ката- логов PATH пользователя. Такие средства, как venv
    1
    , изменяют содержимое
    PATH для использования альтернативных исполняемых файлов python3
    ; они успешно работают в этой схеме.
    СОВЕТ
    Если в системах UNIX каталог с файлом присутствует в переменной среды
    PATH текущего пользователя, а файл является исполняемым, то для выпол- нения из командного интерпретатора достаточно указать только имя файла.
    Чтобы назначить файл исполняемым, введите следующую команду:
    $ chmod +x <путь/к/file.py>
    26.5. Строка документации
    В начале файла модуля может располагаться строка документации уров- ня модуля. Она должна следовать за строкой с
    #!
    , но предшествовать любому коду Python. Строка документации содержит обзор модуля, и в ней должна содержаться сводная информация о коде. Кроме того, в ней могут содержаться примеры использования модуля.
    СОВЕТ
    Python включает библиотеку doctest для проверки примеров из интерак- тивного интерпретатора. Использование строк документации, содержащих фрагменты кода REPL, могут служить как для документации, так и для про- стой проверки логики своей библиотеки.
    В файле cat.py код doctest содержится в конце строки документации. При запуске cat.py с ключом
    --run-tests библиотека doctest перебирает все существующие строки документации и проверяет содержащийся в них код.
    Данная возможность приведена только для демонстрации: обычно возмож- ность выполнения тестов в сценарии не отображается для рядовых пользова- телей, не являющихся разработчиками, даже если вы включили код doctest в строку документации. В данном случае параметр
    --run-test включен как пример использования модуля doctest
    1
    https://docs.python.org/3/library/venv.html

    26.7. Метаданные и глобальные переменные
    257
    26.6. Импортирование
    Команды импортирования обычно включаются в начало модулей Python.
    Строки import принято группировать по местонахождению библиотеки.
    Сначала перечисляются библиотеки, входящие в стандартную библи- отеку Python. Далее следуют сторонние библиотеки, и в последнюю очередь перечисляются библиотеки, локальные для текущего кода. Такая структура кода позволит конечным пользователям быстро просмотреть команды импорта, требования и источники происхождения кода.
    26.7. Метаданные и глобальные
    переменные
    Если у вас имеются глобальные переменные уровня модуля, определите их после команд импортирования. Это позволит просмотреть модуль и быстро определить, что собой представляют глобальные переменные.
    Глобальные переменные определяются на уровне модуля, и они доступны в границах этого модуля. Так как Python позволяет изменить любую пере- менную, глобальные переменные являются потенциальным источником ошибок. Кроме того, код проще понять, когда переменные определяются и изменяются только в области видимости функции. Тогда вы можете быть твердо уверены в том, с какими данными вы работаете и кто их изменяет.
    Если глобальная переменная изменяется в нескольких местах (и особенно в разных модулях), вы своими руками готовите себе долгий сеанс отладки.
    Один из допустимых вариантов использования глобальных перемен- ных — эмуляция констант из других языков программирования. Кон- станта аналогична переменной, но ее значение не может изменяться.
    В Python не поддерживаются переменные, которые не могут изменяться, но вы можете воспользоваться специальными обозначениями, указы- вающими, что переменная должна рассматриваться в программе как доступная только для чтения. В PEP 8 указано, что имена глобальных констант должны назначаться по тем же правилам, что и имена пере- менных, но они должны быть записаны прописными буквами. Например, если вы хотите использовать в программе пропорцию золотого сечения, соответствующее значение может быть определено так:
    >>> GOLDEN_RATIO = 1.618

    258
    Глава 26. Полноценный пример
    Если этот код определяется в модуле, регистр символов подсказывает, что программа не должна изменять связывание этой переменной.
    ПРИМЕЧАНИЕ
    Определяя константы в виде глобальных переменных и используя тщательно продуманные имена, можно избежать проблемы, встречающейся в програм- мировании, — так называемых «волшебных чисел». Под «волшебным числом» понимается число, присутствующее в коде или формуле, которое не хранится в переменной. Это само по себе достаточно плохо, особенно когда кто-то пытается разобраться в вашем коде.
    Другая проблема с «волшебными числами» заключается в том, что значения со временем нередко распространяются в коде. Это не создаст проблем, пока вы не захотите изменить это значение. Что делать — провести поиск с заменой?
    А если «волшебное число» на самом деле представляет два разных значения — например, число сторон треугольника и размерность окружающего мира?
    В этом случае глобальный поиск с заменой приведет к появлению ошибок.
    Обе проблемы (контекст и повторение) решаются сохранением значения в именованной переменной. Таким образом у переменной образуется кон- текст, а у числа появляется имя. Оно также позволяет легко изменить зна- чение в одном месте.
    Кроме глобальных переменных, на этом уровне также существуют пере- менные метаданных. В метаданных хранится информация о модуле: автор, версия и т. д. Обычно метаданные хранятся в «специальных» пере- менных с двойными подчеркиваниями (
    __author__
    ). Например, PEP 396 рекомендует хранить версию модуля в строковой переменной
    __version__
    на глобальном уровне модуля.
    1   ...   13   14   15   16   17   18   19   20   21


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