Управляемся с изменением требований
Рефакторинг
Выводы
Файлы
Файлы
«девять миль ходьбы это не шутка, особенно во время дождя.» —Harry Kemelman, The Nine Mile Walk
На моём Windows ноутбуке было 38493 файла, прежде чем я установил одно приложение. Установка Python 3 добавила почти 3000 файлов к общему объёму. Файлы представляют собой первичную парадигму хранения информации в основных операционных системах; эта концепция настолько укоренилась, что большинство людей не воспримут нечто другое альтернативное. Образно говоря, Ваш компьютер тонет в море файлов.
Чтение из текстовых файлов
Прежде чем читать из текстового файла, его требуется открыть. Открытие файла в Python легко выполнить:
a_file = open('examples/chinese.txt', encoding='utf-8')
Python имеет встроенную функцию open(), которой передается имя файла в качестве аргумента. В примере имя файла 'examples/chinese.txt' и в нём есть 5 интересных вещей:
- Это не просто имя файла, это комбинация пути к каталогу и имя файла. Гипотетически, в функцию открытия файла можно было бы передать два параметра: путь к файлу и имя файла, но в функцию open() можно передать только один. В Python, когда это необходимо вы можете включать все или некоторые пути к каталогу.
- При указании пути к каталогу используется / (прямая обратная черта, слэш, правый слэш), не обсуждая какая операционная система используется. Windows использует \ (обратную косую черту, обратный слэш, слэш влево) для указания пути к каталогам, а операционные системы Linux и MacOS используют / (прямая обратная черта, слэш, правый слэш). В Python прямой слэш просто работает всегда, даже на Windows.
- Путь каталога не начинается с косой черты (слэша) или буквы, это называется относительным путем. Относительно чего? Имей терпение, кузнечик!
- Это строки. Все современные операционные системы (включая Windows) используют Unicode для хранения имён файлов и директорий. Python 3 полностью поддерживает не-ascii пути.
- Файл не обязательно должен находиться на локальных дисках. Вы можете использовать сетевые диски. Этот файл может быть объектом виртуальной файловой системы (/proc в linux). Если ваш компьютер считает это за файл и даёт возможность обращаться к этому как к файлу, то Python сможет открыть этот файл.
Вызов функции open() не ограничивается передачей параметра пути к файлу и его имени. Имеется ещё один параметр, называющийся encoding. О да, дорогой читатель, это звучит воистину ужасно!
Особенности кодировки показывают своё страшное лицо
Байты байт; символы абстракции. Строка представляет собой последовательность символов в кодировке Юникод. Но файлы на диске не являются последовательностью символов в кодировке Unicode, а являются последовательностью байтов. Если вы читаете текстовый файл с диска, то как Python преобразует эту последовательность байт в последовательность символов? Он декодирует байт по определенному алгоритму кодировки и возвращает последовательность символов в кодировке Unicode (т. е. в виде строки).
>> file = open('examples/chinese.txt')…>>> a_string = file.read()…Traceback (most recent call last):… File «<stdin>», line 1, in <module>… File «C:\Python31\lib\encodings\cp1252.py», line 23, in decode… return codecs.charmap_decode(input, self.errors, decoding_table)[0]…UnicodeDecodeError: 'charmap' codec can’t decode byte 0x8f in position 28: character maps to <undefined> [[Категория:Погружение в Python 3]]XML
Погружение
Большинство глав в этой книге строятся на отрывках, примерах кода. Но xml это больше данные, нежели код. Один из способов применения xml это «синдикация контента» такого, как последние статьи с блога, форума или других часто обновляемых сайтов. Большинство популярного ПО для ведения блогов может создавать ленты (фиды) и обновлять их, когда новые статьи, темы публикуются. Вы можете следить за блогом подписавшись на его канал, также вы можете следить за несколькими блогами при помощи «программ-агрегаторов» таких, как Google Reader [1]
Итак, ниже представлены XML данные с которыми мы будем работать в этой главе. Это фид формата Atom syndication feed
<?xml version='1.0' encoding='utf-8'?><feed xmlns='http://www.w3.org/2005/Atom' xml:lang='en'> <title>dive into mark</title> <subtitle>currently between addictions</subtitle> <id>tag:diveintomark.org,2001-07-29:/</id> <updated>2009-03-27T21:56:07Z</updated> <link rel='alternate' type='text/html' href='http://diveintomark.org/'/> <link rel='self' type='application/atom+xml' href='http://diveintomark.org/feed/'/> <entry> <author> <name>Mark</name> <uri>http://diveintomark.org/</uri> </author> <title>Dive into history, 2009 edition</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2009/03/27/dive-into-history-2009-edition'/> <id>tag:diveintomark.org,2009-03-27:/archives/20090327172042</id> <updated>2009-03-27T21:56:07Z</updated> <published>2009-03-27T17:20:42Z</published> <category scheme='http://diveintomark.org' term='diveintopython'/> <category scheme='http://diveintomark.org' term='docbook'/> <category scheme='http://diveintomark.org' term='html'/> <summary type='html'>Putting an entire chapter on one page sounds bloated, but consider this &mdash; my longest chapter so far would be 75 printed pages, and it loads in under 5 seconds&hellip; On dialup.</summary> </entry> <entry> <author> <name>Mark</name> <uri>http://diveintomark.org/</uri> </author> <title>Accessibility is a harsh mistress</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2009/03/21/accessibility-is-a-harsh-mistress'/> <id>tag:diveintomark.org,2009-03-21:/archives/20090321200928</id> <updated>2009-03-22T01:05:37Z</updated> <published>2009-03-21T20:09:28Z</published> <category scheme='http://diveintomark.org' term='accessibility'/> <summary type='html'>The accessibility orthodoxy does not permit people to question the value of features that are rarely useful and rarely used.</summary> </entry> <entry> <author> <name>Mark</name> </author> <title>A gentle introduction to video encoding, part 1: container formats</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2008/12/18/give-part-1-container-formats'/> <id>tag:diveintomark.org,2008-12-18:/archives/20081218155422</id> <updated>2009-01-11T19:39:22Z</updated> <published>2008-12-18T15:54:22Z</published> <category scheme='http://diveintomark.org' term='asf'/> <category scheme='http://diveintomark.org' term='avi'/> <category scheme='http://diveintomark.org' term='encoding'/> <category scheme='http://diveintomark.org' term='flv'/> <category scheme='http://diveintomark.org' term='GIVE'/> <category scheme='http://diveintomark.org' term='mp4'/> <category scheme='http://diveintomark.org' term='ogg'/> <category scheme='http://diveintomark.org' term='video'/> <summary type='html'>These notes will eventually become part of a tech talk on video encoding.</summary> </entry></feed>Минутное введение в XML
Если Вы уже знакомы с XML, то можете пропустить эту главу.
XML — это язык разметки для описания иерархии структурированных данных. XML документ содержит один или более элементов разделённых открывающими и закрывающими тегами. Это правильный, хотя и неинтересный, XML документ:
<foo> ①</foo> ②① Это открывающий (начальный) тег элемента foo.
② Это соответствующий закрывающий (конечный) тег элемента foo. Как в математике и языках программирования каждая открывающая скобка должна иметь соответствующую закрывающую, в XML каждый открывающий тег должен быть закрыт соответствующим закрывающим.
Элементы могут быть неограниченно вложены друг в друга. Так как элемент bar вложен в элемент foo, то его называют подэлементом или дочерним элементом элемента foo.
<foo> <bar></bar></foo>Первый элемент каждого XML документа называется корневым. XML документ может содержать только один корневой элемент. Пример представленный ниже не является XML документом, так как он имеет два корневых элемента:
<foo></foo><bar></bar>Элементы могут иметь атрибуты состоящие из пары имя-значение. Атрибуты перечисляются внутри открывающего тега элемента и разделяются пробелами. [wаp-rоbin.com] Имена атрибутов не могут повторяться внутри одно элемента. Значения атрибутов должны быть обрамлены одинарными или двойными кавычками.
<foo lang='en'> ① <bar id='papayawhip' lang="fr"></bar> ②</foo>① Элемент foo имеет один атрибут именованный как lang. Значению атрибута lang присваивается строка en.
② Элемент bar имеет два атрибута: id и lang. Значение lang есть fr. Это не приводит к конфликту с атрибутом lang элемента foo, так как каждый элемент имеет свой набор атрибутов.
Если элемент имеет больше чем один атрибут, то порядок атрибутов не играет роли. Атрибуты элементов есть неупорядоченный набор ключей и значений подобно словарям в Python. Для каждого элемента можно указать неограниченное число атрибутов.
Элементы могут иметь текст (текстовое содержание).
<foo lang='en'> <bar lang='fr'>PapayaWhip</bar></foo>Элементы которые не содержат текста и дочерних элементов называются пустыми.
<foo></foo>Существует сокращённая запись пустого элемента. Поместив знак дроби / в конце открывающего тега, вы можете пропустить закрывающий тег. XML документ предыдущего примера с пустым элементов может быть записан следующим образом:
<foo/>Подобно тому как функции Python могут быть объявлены в разных модулях, XML элементы могут быть объявлены в разных пространствах имён (namespaces). Пространства имён обычно выглядят как URL-пути. Для объявления пространства имён по умолчанию используется директива xmlns. Объявление пространства имён очень похоже на атрибут, но имеет специальное значение.
<feed xmlns='http://www.w3.org/2005/Atom'> ① <title>dive into mark</title> ②</feed>① Элемент feed находится в пространстве имён http://www.w3.org/2005/Atom.
② Элемент title также находится в пространстве имён http://www.w3.org/2005/Atom. Пространство имён применяется как к элементу в котором оно было определено так и ко всем дочерним элементам.
Вы можете объявлять пространство имён xmlns:prefix и ставить ему в соответствие префикс prefix. Тогда каждый элемент в данном пространстве имён должен быть явно объявлен с указанием префикса prefix.
<atom:feed xmlns:atom='http://www.w3.org/2005/Atom'> ① <atom:title>dive into mark</atom:title> ②</atom:feed>① Элемент feed находится в пространстве имён http://www.w3.org/2005/Atom.
② Элемент title также находится в пространстве имён http://www.w3.org/2005/Atom.
С точки зрения синтаксического анализатора XML, предыдущие два XML документа идентичны. Пара «пространство имён» + «имя элемента» задают XML идентичность. Префиксы используются только для ссылки на пространство имён, но не изменяют имени атрибута. Если пространства имён совпадают, имена элементов совпадают, атрибуты (или их отсутствие) совпадают и тексты элементов совпадают, то XML документы одинаковы.
И, наконец, XML документы могут содержать информацию о кодировке символов в первой строке до корневого элемента. (Если Вам интересно как документ может содержать информацию которая должна быть известна XML-анализатору до анализа XML документа, то смотрите Catch-22 раздел F XML спецификации)
<?xml version='1.0' encoding='utf-8'?>Теперь Вы знаете об XML достаточно чтобы «вынести» следующие разделы главы!