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

  • Использование итераторов и представлений

  • 3 True>>>В Python 3 такая операция приведет к исключению TypeError. Например:>>> 3

  • Имена файлов, аргументов и переменных окружения

  • Реорганизация библиотеки

  • Импортирование по абсолютному пути

  • Перенос программного кода и утилита 2to3

  • Перенос программного кода на версию Python 2.6

  • Полный охват программы тестами

  • Использование утилиты 2to3

  • справочник по Python. мм isbn 9785932861578 9 785932 861578


    Скачать 4.21 Mb.
    Названиемм isbn 9785932861578 9 785932 861578
    Анкорсправочник по Python
    Дата08.05.2022
    Размер4.21 Mb.
    Формат файлаpdf
    Имя файлаBizli_Python-Podrobnyy-spravochnik.440222.pdf
    ТипСправочник
    #518195
    страница72 из 82
    1   ...   68   69   70   71   72   73   74   75   ...   82
    f.write(“Hello World\n”)
    Traceback (most recent call last):
    File “”, line 1, in
    File “/tmp/lib/python3.0/io.py”, line 1035, in write raise TypeError(“can’t write str to binary stream”)
    TypeError: can’t write str to binary stream
    (Перевод:
    Трассировочная информация (самый последний вызов – самый нижний):
    Файл “”, строка 1, в
    Файл “/tmp/lib/python3.0/io.py”, строка 1035, в write raise TypeError(“невозможно записать данные типа str в двоичный поток”)
    TypeError: невозможно записать данные типа str в двоичный поток
    )
    >>>
    Как известно, сокеты, каналы и некоторые другие типы потоков ввода- вывода всегда действуют в двоичном режиме. Одна из потенциальных про- блем, которые могут возникнуть при работе с сетями, состоит в том, что многие протоколы (такие как HTTP, SMTP, FTP и другие) подразумевают работу с запросами/ответами в виде текста. Учитывая, что сокеты действу- ют в двоичном режиме, происходит смешивание операций ввода-вывода двоичных данных с обработкой текстовой информации, что может приво- дить к проблемам, о которых рассказывалось в предыдущем разделе. Будь- те предельно внимательны.

    784
    Приложение A. Python 3
    Функции print() и exec()
    Инструкции print и exec в версии Python 2 теперь стали функциями. Ниже приводятся некоторые примеры использования функции print(), в сравне- нии с использованием инструкции print в Python 2:
    print(x,y,z) # То же, что и : print x, y, z print(x,y,z,end=’ ‘) # То же, что и : print x, y, z,
    print(a,file=f) # То же, что и : print >>f, a
    Тот факт, что инструкция print превратилась в функцию print(), означает, что в случае необходимости ее можно заменить альтернативной реализа- цией.
    Инструкция exec также превратилась в функцию exec(), но ее поведение в Python 3 несколько изменилось по сравнению с Python 2. Рассмотрим в качестве примера следующий фрагмент:
    def foo():
    exec(“a = 42”)
    print(a)
    В Python 2 при вызове функции foo() будет выведено число ‘42’. В Python 3 будет возбуждено исключение NameError с сообщением о том, что имя пере- менной a не определено. Проблема состоит в том, что функция exec(), как функция, оперирует только словарями, возвращаемыми функциями glo- bals()
    и locals(). Однако словарь, возвращаемый функцией locals()
    , в дей- ствительности является копией словаря с локальными переменными.
    Присваивание, выполненное функцией exec(), изменит копию локальной переменной, но не саму локальную переменную. Ниже приводится один из способов решения этой проблемы:
    def foo():
    _locals = locals()
    exec(“a = 42”,globals(),_locals)
    a = _locals[‘a’] # Извлечет значение переменной из копии print(a)
    И вообще, не следует ожидать, что Python 3 будет поддерживать тот же уровень «волшебства», который поддерживался функциями exec(), eval() и execfile() в Python 2. Более того, функция execfile() вообще была убрана из языка (ее можно имитировать, передав открытый объект файла функ- ции exec()).
    Использование итераторов и представлений
    В Python 3 итераторы и генераторы используются намного шире, чем в Py-
    Python 3 итераторы и генераторы используются намного шире, чем в Py-
    3 итераторы и генераторы используются намного шире, чем в Py-
    Py- thon 2. Встроенные функции, такие как zip(), map() и range(), раньше воз- вращавшие списки, теперь возвращают итераторы. Чтобы создать список из значения, возвращаемого такой функцией, можно использовать функ- цию list().
    В Python 3 используется несколько иной подход к извлечению ключей и значений из словарей. В Python 2, чтобы получить список ключей, значе-
    Python 2, чтобы получить список ключей, значе-
    2, чтобы получить список ключей, значе-

    Типичные ошибки
    785
    ний или пар ключ/значение, можно было использовать такие методы, как
    d.keys()
    , d.values() или d.items() соответственно. В Python 3 эти методы воз-
    Python 3 эти методы воз-
    3 эти методы воз- вращают так называемые объекты представлений. Например:
    >>> s = { ‘GOOG’: 490.10, ‘AAPL’: 123.45, ‘IBM’: 91.10 }
    >>> k = s.keys()
    >>> k

    >>> v = s.values()
    >>> v

    >>>
    Эти объекты поддерживают итерации, поэтому для просмотра их содержи- мого можно использовать цикл for. Например:
    >>> for x in k:
    ...
    print(x)
    ...
    GOOG
    AAPL
    IBM
    >>>
    Объекты представлений всегда можно преобразовать обратно в словари, из которых они были получены. Одна из важных особенностей этих объектов состоит в том, что изменения в словаре приводят к изменению элементов, возвращаемых представлением. Например:
    >>> s[‘ACME’] = 5612.25
    >>> for x in k:
    ...
    print(x)
    ...
    GOOG
    AAPL
    IBM
    ACME
    >>>
    Чтобы создать список ключей или значений словаря, достаточно просто воспользоваться функцией list(), например list(s.keys()).
    Целые числа и целочисленное деление
    В Python 3 больше нет типа int, соответствующего 32-битовым целым чис- лам, и отдельного типа, соответствующего длинным целым числам. Теперь тип int представляет целые числа произвольной точности (подробности внутренней реализации этого типа недоступны пользователю).
    Кроме того, операция целочисленного деления теперь всегда возвращает число с плавающей точкой. Например, результатом деления 3/5 будет чис- будет чис- чис- чис- ло 0.6, а не 0. Преобразование в число с плавающей точкой производится, даже если результат может быть представлен целым числом. Например, результатом деления 8/2 будет число 4.0, а не 4.

    786
    Приложение A. Python 3
    Сравнивание
    В Python 3 реализована более строгая процедура сравнивания значений.
    В Python 2 допускается сравнивать объекты, даже если такая операция сравнивания не имеет смысла. Например:
    >>> 3 < “Hello”
    True
    >>>
    В Python 3 такая операция приведет к исключению TypeError. Например:
    >>> 3 < “Hello”
    Traceback (most recent call last):
    File “”, line 1, in
    TypeError: unorderable types: int() < str()
    (Перевод:
    Трассировочная информация (самый последний вызов – самый нижний):
    Файл “”, строка 1, в
    TypeError: несравнимые типы: int() < str()
    )
    >>>
    Это не очень существенное изменение, но оно означает, что в Python 3 не-
    Python 3 не-
    3 не- обходимо быть более внимательными к типам сравниваемых значений.
    Например, если вы собираетесь использовать метод sort() списка, все эле- менты этого списка должны быть совместимы с оператором <, в противном случае будет возбуждено исключение. В Python 2 операция была бы вы-
    Python 2 операция была бы вы-
    2 операция была бы вы- полнена без сообщения об ошибке, обычно с бессмысленным результатом.
    Итераторы и генераторы
    В Python 3 были внесены незначительные изменения в протокол итерато- ров. Ранее, чтобы получить итератор объекта, вызывался метод __iter__() и затем в каждой итерации вызывался метод next(). Теперь метод next() переименован в __next__(). Для большинства пользователей эти изменения незаметны, за исключением случаев, когда пишется программный код, ко- торый выполняет итерации вручную, или когда объявляется собственный объект итератора. Не забудьте изменить имя метода next() в своих классах.
    Для обеспечения переносимости используйте встроенную функцию next(), которая вызывает метод next() или __next__().
    Имена файлов, аргументов и переменных окружения
    В Python 3 имена файлов, аргументов командной строки в переменной sys.argv и переменных окружения в os.environ могут интерпретироваться как строки Юникода, в зависимости от региональных настроек системы.
    Единственная проблема состоит в том, что использование Юникода в пре- делах операционной системы может поддерживаться недостаточно полно.
    Например, во многих системах технически может быть возможным ука- зывать имена файлов, параметры командной строки и имена переменных окружения только в виде последовательностей байтов, которые не соот- ветствуют допустимой кодировке Юникода. Такие ситуации на практике

    Типичные ошибки
    787
    встречаются достаточно редко, тем не менее об этом следует помнить при использовании языка Python для решения задач системного администри-
    Python для решения задач системного администри- для решения задач системного администри- рования. Как уже отмечалось ранее, подобные проблемы легко можно ре- шить, передавая имена файлов и каталогов в виде строк байтов. Например, os.listdir(b’/foo’)
    Реорганизация библиотеки
    В Python 3 были реорганизованы и переименованы некоторые части стан-
    Python 3 были реорганизованы и переименованы некоторые части стан-
    3 были реорганизованы и переименованы некоторые части стан- дартной библиотеки. Наиболее заметные изменения произошли в коллек- ции модулей, связанных с сетевыми взаимодействиями и поддержкой фор- матов данных, используемых в Интернете. Кроме того, из библиотеки было исключено большое количество устаревших модулей (например, gopherlib, rfc822
    и другие).
    Теперь стандартной практикой стало использовать в именах модулей толь- ко символы нижнего регистра. Некоторые модули, такие как ConfigParser,
    Queue и SocketServer, были переименованы в configparser, queue и socketserver соответственно. Вы также должны стараться следовать этому соглашению при создании своих модулей.
    Для реорганизации программного кода, ранее содержавшегося в разроз- ненных модулях, были созданы новые пакеты. Например, был создан пакет http
    , включающий в себя все модули, используемые для разработки сер- веров HTTP; все модули, предназначенные для парсинга разметки HTML, были собраны в пакете html; модули, реализующие технологии XML-RPC, были помещены в пакет xmlrpc, и так далее.
    Если говорить о нерекомендуемых модулях, то в этой книге были представ- лены только те модули, которые в настоящее время используются в версиях
    Python 2.6 и Python 3.0. Если в существующих программах, написанных для Python 2, вам встретятся модули, не описанные здесь, велика вероят-
    Python 2, вам встретятся модули, не описанные здесь, велика вероят-
    2, вам встретятся модули, не описанные здесь, велика вероят- ность что эти модули были объявлены нерекомендуемыми в пользу чего-то более современного. Например, в Python 3 отсутствует модуль popen2, часто используемый в Python 2 для запуска дочерних процессов. Вместо него же-
    Python 2 для запуска дочерних процессов. Вместо него же-
    2 для запуска дочерних процессов. Вместо него же- него же- него же- же- же- лательно использовать модуль subprocess.
    Импортирование по абсолютному пути
    Реорганизация библиотеки коснулась также всех инструкций import, при- сутствующих в подмодулях пакетов, – в них теперь используются абсолют- ные имена. Подробнее об этом рассказывается в главе 8 «Модули, пакеты и дистрибутивы», но, в качестве примера, представьте, что у вас имеется пакет со следующей организацией:
    foo/
    __init__.py spam.py bar.py
    Если в файле spam.py использовать инструкцию import bar, будет возбужде- но исключение ImportError, несмотря на то, что файл bar.py находится в том же самом каталоге. Чтобы импортировать этот подмодуль, в файле spam.py

    788
    Приложение A. Python 3 необходимо использовать инструкцию import foo.bar или выполнить им- порт относительно пакета, например from . import bar.
    В Python 2 инструкция import всегда сначала проверяет текущий каталог в поисках соответствия, и только потом переходит к проверке других ката- логов, указанных в sys.path.
    Перенос программного кода и утилита 2to3
    Перенос существующего программного кода с версии Python 2 на версию
    Python 3 является достаточно непростой задачей. Чтобы сразу прояснить ситуацию, нужно заметить, что не существует никаких волшебных моду- лей, флагов, переменных окружения или других инструментов, которые позволили бы интерпретатору Python 3 выполнять любые программы, написанные для Python 2. Тем не менее существуют определенные шаги, представленные ниже, которые помогут выполнить перенос программного кода.
    Перенос программного кода на версию Python 2.6
    При переносе программного кода на Python 3 сначала рекомендуется вы-
    Python 3 сначала рекомендуется вы-
    3 сначала рекомендуется вы- полнить перенос на версию Python 2.6. Дело в том, что версия Python 2.6 не только имеет обратную совместимость с версией Python 2.5, но она также поддерживает некоторые новые особенности, присутствующие в Python 3.
    В качестве примеров можно привести улучшенный механизм форматиро- вания строк, новый синтаксис исключений, литералы строк байтов, би- блиотеку ввода-вывода и абстрактные базовые классы. Благодаря этому программа, написанная для Python 2, сможет использовать полезные пре-
    Python 2, сможет использовать полезные пре-
    2, сможет использовать полезные пре- имущества Python 3, даже если она еще не готова полностью к переносу на версию Python 3.
    Еще одна причина в пользу переноса на версию Python 2.6 состоит в том, что при запуске с ключом -3 интерпретатор Python 2.6 выводит предупре-
    Python 2.6 выводит предупре-
    2.6 выводит предупре- ждения, когда встречается с использованием нерекомендуемых возможно- стей. Например:
    bash-3.2$ python -3
    Python 2.6 (trunk:66714:66715M, Oct 1 2008, 18:36:04)
    [GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
    Type “help”, “copyright”, “credits” or “license” for more information.
    >>> a = { }
    >>> a.has_key(‘foo’)
    __main__:1: DeprecationWarning: dict.has_key() not supported in 3.x; use the in operator
    (Перевод:
    __main__:1: DeprecationWarning: dict.has_key() не поддерживается в версии 3.x; используйте оператор in
    )
    False
    >>

    Перенос программного кода и утилита 2to3
    789
    Опираясь на эти предупреждения, необходимо внести изменения в про- грамму и добиться их отсутствия при работе программы под управлением
    Python 2.6, после чего можно приступать к переносу программы на версию
    Python 3.
    Полный охват программы тестами
    В стандартной библиотеке Python имеются удобные модули, обеспечиваю-
    Python имеются удобные модули, обеспечиваю- имеются удобные модули, обеспечиваю- щие возможность тестирования, включая doctest и unittest. Убедитесь, что программа полностью охвачена тестами, прежде чем приступать к перено- су на версию Python 3. Если к данному этапу в программе вообще не было никаких тестов, самое время приступить к их созданию. Вам потребуется обеспечить максимально полный охват программы тестами и убедиться, что при запуске под управлением Python 2.6 все тесты выполняются без вывода предупреждений.
    Использование утилиты 2to3
    В состав Python 3 входит утилита с именем 2to3, которая может помочь в пе- реносе программного кода с версии Python 2.6 на версию Python 3. Обычно эта утилита находится в каталоге Tools/scripts, внутри дистрибутива с ис- ходными текстами, и в большинстве систем устанавливается в тот же ка- талог, что и выполняемый файл python3.0. Это утилита командной строки, которая обычно запускается в командной оболочке UNIX или Windows.
    В качестве примера рассмотрим следующую программу, использующую ряд нерекомендуемых особенностей.
    # example.py import ConfigParser
    ёёё
    for i in xrange(10):
    print i, 2*i
    ёёё
    def spam(d):
    if not d.has_key(“spam”):
    d[“spam”] = load_spam()
    return d[“spam”]
    Чтобы обработать эту программу утилитой 2to3, выполните команду 2to3 example.py
    . Например:
    % 2to3 example.py
    RefactoringTool: Skipping implicit fixer: buffer
    RefactoringTool: Skipping implicit fixer: idioms
    RefactoringTool: Skipping implicit fixer: set_literal
    RefactoringTool: Skipping implicit fixer: ws_comma
    --- example.py (original)
    +++ example.py (refactored)
    @@ -1,10 +1,10 @@
    # example.py
    -import ConfigParser
    +import configparser
    ёёё

    790
    Приложение A. Python 3
    -for i in xrange(10):
    - print i, 2*i
    +for i in range(10):
    + print(i, 2*i)
    ёёё
    def spam(d):
    - if not d.has_key(“spam”):
    + if “spam” not in d:
    d[“spam”] = load_spam()
    return d[“spam”]
    RefactoringTool: Files that need to be modified:
    RefactoringTool: example.py
    Как видно из листинга, утилита 2to3 смогла идентифицировать части про- граммы, которые могут считаться проблематичными и, вероятно, должны быть изменены. Они показаны в формате вывода утилиты diff. В данном примере мы применили утилиту 2to3 к единственному файлу, однако если ей передать имя каталога, она рекурсивно обойдет все файлы с исходными текстами на языке Python, присутствующие в дереве каталогов, и создаст отчет для каждого из них.
    По умолчанию утилита 2to3 не исправляет обнаруженные проблемы в ис- ходных файлах, она просто сообщает о фрагментах программного кода, которые требуется изменить. Основная сложность, с которой приходится сталкиваться при работе с утилитой 2to3, заключается в недостатке инфор- мации. Например, взгляните на функцию spam(). Эта функция вызывает метод d.has_key(). В словарях метод has_key() был удален в пользу оператора in
    . Утилита 2to3 сообщает о необходимости замены вызова этого метода, но без дополнительной информации непонятно, действительно ли функция spam()
    работает со словарем. Может оказаться, что d является экземпляром какого-либо другого класса (например, базы данных), реализующего ме- тод has_key(), и тогда замена вызова метода оператором in может оказаться ошибкой. Еще одна проблема, которая может возникнуть при использо- вании утилиты 2to3, – это обработка строк байтов и строк Юникода. Учи- тывая, что Python 2 автоматически преобразует строки байтов в строки
    Юникода, достаточно часто можно встретить программный код, в котором эти два строковых типа смешиваются по невнимательности программи- ста. К сожалению, утилита 2to3 неспособна обнаружить эту проблему. Это одна из причин, почему так важно иметь как можно более полный охват программы тестами. И конечно же, многое зависит от особенностей самого приложения.
    При желании утилиту 2to3 можно заставить исправлять отдельные несо- вместимости. Для начала следует получить список «исправлений», введя команду 2to3 -l. Например:
    %
    1   ...   68   69   70   71   72   73   74   75   ...   82


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