Язык программирования Python
Язык программирования Python читать книгу онлайн
Курс посвящен одному из бурно развивающихся и популярных в настоящее время сценарных языков программирования — Python. Язык Python позволяет быстро создавать как прототипы программных систем, так и сами программные системы, помогает в интеграции программного обеспечения для решения производственных задач. Python имеет богатую стандартную библиотеку и большое количество модулей расширения практически для всех нужд отрасли информационных технологий. Благодаря ясному синтаксису изучение языка не составляет большой проблемы. Написанные на нем программы получаются структурированными по форме, и в них легко проследить логику работы. На примере языка Python рассматриваются такие важные понятия как: объектно–ориентированное программирование, функциональное программирование, событийно–управляемые программы (GUI–приложения), форматы представления данных (Unicode, XML и т.п.). Возможность диалогового режима работы интерпретатора Python позволяет существенно сократить время изучения самого языка и перейти к решению задач в соответствующих предметных областях. Python свободно доступен для многих платформ, а написанные на нем программы обычно переносимы между платформами без изменений. Это обстоятельство позволяет применять для изучения языка любую имеющуюся аппаратную платформу.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Листинг
import xml.dom.minidom
dom = xml.dom.minidom.parse(«expression.xml»)
dom.normalize()
def output_tree(node, level=0):
if node.nodeType == node.TEXT_NODE:
if node.nodeValue.strip():
print ". "*level, node.nodeValue.strip()
else: # ELEMENT_NODE или DOCUMENT_NODE
atts = node.attributes or {}
att_string = ", ".join(
["%s=%s " % (k, v) for k, v in atts.items()])
print ". "*level, node.nodeName, att_string
for child in node.childNodes:
output_tree(child, level+1)
output_tree(dom)
В этом примере дерево выводится с помощью определенной функции output_tree(), которая принимает на входе узел и вызывается рекурсивно для всех вложенных узлов.
В результате получается примерно следующее:
Листинг
#document
. expression
. . operation type=+
… operand
… . 2
… operand
… . operation type=*
… . . operand
… … 3
… . . operand
… … 4
Здесь же применяется метод normalize() для того, чтобы все текстовые фрагменты были слиты воедино (в противном случае может следовать подряд несколько узлов с текстом).
Можно заметить, что даже в небольшом примере использовались атрибуты узлов: node.nodeType указывает тип узла, node.nodeValue применяется для доступа к данным, node.nodeName дает имя узла (соответствует названию тега), node.attributes дает доступ к атрибутам узла. node.childNodes применяется для доступа к дочерним узлам. Этих свойств достаточно, чтобы рекурсивно обойти дерево.
Все узлы являются экземплярами подклассов класса Node. Они могут быть следующих типов:
Название Описание Метод для создания
ELEMENT_NODE Элемент createElement(tagname)
ATTRIBUTE_NODE Атрибут createAttribute(name)
TEXT_NODE Текстовый узел createTextNode(data)
CDATA_SECTION_NODE Раздел CDATA
ENTITY_REFERENCE_NODE Ссылка на сущность
ENTITY_NODE Сущность
PROCESSING_INSTRUCTION_NODE Инструкция по обработке createProcessingInstruction(target, data)
COMMENT_NODE Комментарий createComment(comment)
DOCUMENT_NODE Документ
DOCUMENT_TYPE_NODE Тип документа
DOCUMENT_FRAGMENT_NODE Фрагмент документа
NOTATION_NODE Нотация
В DOM документ является деревом, в узлах которого стоят объекты нескольких возможных типов. Узлы могут иметь атрибуты или данные. Доступ к узлам можно осуществлять через атрибуты вроде childNodes (дочерние узлы), firstChild (первый дочерний узел), lastChild (последний дочерний узел), parentNode (родитель), nextSibling (следующий брат), previousSibling (предыдущий брат).
Выше уже говорилось о методе appendChild(). К нему можно добавить методы insertBefore(newChild, refChild) (вставить newChild до refChild), removeChild(oldChild) (удалить дочерний узел), replaceChild(newChild, oldChild) (заметить oldChild на newChild). Есть еще метод cloneNode(deep), который клонирует узел (вместе с дочерними узлами, если задан deep=1).
Узел типа ELEMENT_NODE, помимо перечисленных методов «просто» узла, имеет много других методов. Вот основные из них:
Листинг
tagName
Имя типа элемента.
Листинг
getElementsByTagName(tagname)
Получает элементы с указанным именем tagname среди всех потомков данного элемента.
Листинг
getAttribute(attname)
Получить значение атрибута с именем attname.
Листинг
getAttributeNode(attrname)
Возвращает атрибут с именем attrname в виде объекта–узла.
Листинг
removeAttribute(attname)
Удалить атрибут с именем attname.
Листинг
removeAttributeNode(oldAttr)
Удалить атрибут oldAttr (задан в виде объекта–узла).
Листинг
setAttribute(attname, value)
Устанавливает значение атрибута attname равным строке value.
Листинг
setAttributeNode(newAttr)
Добавляет новый узел–атрибут к элементу. Старый атрибут заменяется, если имеет то же имя.
Здесь стоит заметить, что атрибуты в рамках элемента повторяться не должны. Их порядок также не важен с точки зрения информационной модели XML.
В качестве упражнения предлагается составить функцию, которая будет вычислять значение выражения, заданного в XML–представлении.
Пространства имен
Еще одной интересной особенностью XML, о которой нельзя не упомянуть, являются пространства имен. Они позволяют составлять XML–документы из кусков различных схем. Например, таким образом в XML–документ можно включить кусок HTML, указав во всех элементах HTML принадлежность особому пространству имен.
Следующий пример XML–кода показывает синтаксис пространств имен (файл foaf.rdf):
Листинг
<?xml version=«1.0» encoding=«UTF–8»?>
<rdf:RDF
xmlns:dc=«http://http://purl.org/dc/elements/1.1/"
xmlns:rdfs=«http://www.w3.org/2000/01/rdf–schema#"
xmlns:foaf=«http://xmlns.com/foaf/0.1/"
xmlns:rdf=«http://www.w3.org/1999/02/22–rdf–syntax–ns#"
>
<rdf:Description rdf:nodeID="_:jCBxPziO1»>
<foaf:nick>donna</foaf:nick>
<foaf:name>Donna Fales</foaf:name>
<rdf:type rdf:resource=«http://xmlns.com/foaf/0.1/Person»/>
</rdf:Description>
</rdf:RDF>
Примечание:
Пример позаимствован из пакета cwm, созданного командой разработчиков во главе с Тимом Бернерс–Ли, создателем технологии WWW. Кстати, cwm тоже написан на Python. Пакет cwm служит обработчиком данных общего назначения для семантической сети — новой идеи, продвигаемой Тимом Бернерс–Ли. Коротко суть идеи состоит в том, чтобы сделать современный «веб» много полезнее, формализовав знания в виде распределенной базы XML–документов, по аналогии с тем как WWW представляет собой распределенную базу документов. Отличие глобальной семантической сети от WWW в том, что она даст машинам возможность обрабатывать знания, делая логические выводы на основании заложенной в документах информации.
Названия пространств имен следуют в виде префиксов к названиям элементов. Эти названия — не просто имена. Они соответствуют идентификаторам, которые должны быть заданы в виде URI (Universal Resource Locator, универсальный указатель ресурса). В примере выше упоминаются пять пространств имен (xmlns, dc, rdfs, foaf и rdf), из которых только первое не требует объявления, так как является встроенным. Из них реально использованы только три: (xmlns, foaf и rdf).
Пространства имен позволяют выделять из XML–документа части, относящиеся к различным схемам, что важно для тех инструментов, которые интерпретируют XML.
В пакете xml есть методы, понимающие механизм пространств имен. Обычно такие методы и атрибуты имеют в своем имени буквы NS.
Получить URI, который соответствует пространству имен данного элемента, можно с помощью атрибута namespaceURI.
В следующем примере печатается URI элементов:
Листинг
import xml.dom.minidom
dom = xml.dom.minidom.parse(«ex.xml»)
def output_ns(node):
if node.nodeType == node.ELEMENT_NODE:
print node.nodeName, node.namespaceURI
for child in node.childNodes:
output_ns(child)
output_ns(dom)
Пример выведет:
Листинг
rdf:RDF http://www.w3.org/1999/02/22–rdf–syntax–ns#
rdf:Description http://www.w3.org/1999/02/22–rdf–syntax–ns#
foaf:nick http://xmlns.com/foaf/0.1/
foaf:name http://xmlns.com/foaf/0.1/
rdf:type http://www.w3.org/1999/02/22–rdf–syntax–ns#
Следует заметить, что указание пространства имен может быть сделано для имен не только элементов, но и атрибутов.
Подробнее узнать о работе с пространствами имен в xml–пакетах для Python можно из документации.