<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF132%3APython</id>
		<title>LXF132:Python - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF132%3APython"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF132:Python&amp;action=history"/>
		<updated>2026-05-13T23:35:59Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF132:Python&amp;diff=12188&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF132:Python&amp;diff=12188&amp;oldid=prev"/>
				<updated>2011-06-22T09:35:27Z</updated>
		
		<summary type="html">&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;: '''Учебник ''Python''''' Настоящие задачи, чтобы вы поупражнялись в кодировании&lt;br /&gt;
&lt;br /&gt;
==''Python'': Анимация интерфейса==&lt;br /&gt;
&lt;br /&gt;
{{Цикл/Python}}&lt;br /&gt;
: ''Clutter'' всецело ориентирован на разработку высококлассных пользовательских интерфейсов. '''Ник Вейч''' приправит графику, слегка вышколив кнопки.&lt;br /&gt;
&lt;br /&gt;
''Clutter'' был создан для «оживления» графических интерфейсов, и нам пора посмотреть, как из объектов-актеров создаются кнопки, а затем добавить к ним несколько занятных атрибутов. Но для начала, прежде чем демонстрировать поразительные новые навыки общения с мышью, надо припасти что-то, с чем мы будем взаимодействовать. Как и почти все инструментарии, ''Clutter'' является событийно-ориентированным. То есть, если в приложении происходит что-то значимое, генерируется сигнал. Грубо говоря, другие участки кода ждут этого сигнала и делают что-то в ответ.&lt;br /&gt;
&lt;br /&gt;
Если в ''Clutter'' отметить актера как реагирующего ['''reactive'''], то при любом событии с ним – типа щелчка, переноса, движения над ним курсора мыши и даже набора на клавиатуре – он будет генерировать полный набор сигналов. Каждый из них можно подключить на уровне объекта к методу или функции обратного вызова, обеспечивающей реакцию на сигнал. Чтобы опробовать это, не потребуется даже создавать приложение: все делается в интерактивной оболочке ''Python''. Откройте терминал и введите ''python'', а затем начните ввод (если вы ленивы, можете скопировать код из файла-листинга, имеющегося на '''LXFDVD'''). Приступим:&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Что нам потребуется|Содержание=Прежде чем начать, установите ''Python'' и его модуль ''Clutter''. Если вы используете дистрибутив, обновленный не раньше, чем год назад, то оба доступны в ваших репозиториях. Обычно проще загрузить всё из них, но поискать исходные тексты последней версии ''Clutter'' на http://www.clutter-project.org. Чтобы добавить видео в конце урока, понадобится ''GStreamer'', а также пакеты '''cluttergst''' и '''pyclutter-gst'''.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 import clutter&lt;br /&gt;
&lt;br /&gt;
 def entered(actor,event):&lt;br /&gt;
  print event,actor&lt;br /&gt;
  actor.set_color(clutter.Color(0,0,255,255))&lt;br /&gt;
  return ‘#t’&lt;br /&gt;
&lt;br /&gt;
 def exited(actor,event):&lt;br /&gt;
  print event,actor&lt;br /&gt;
  actor.set_color(clutter.Color(255,0,255,255))&lt;br /&gt;
  return ‘#t’&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы создали функции обратного вызова для двух событий. Неважно, что это за события, и даже неважно, какие объекты их генерируют – функции тождественны. На самом деле, при желании их можно объединить в одну, но наш вариант кода понятнее.&lt;br /&gt;
&lt;br /&gt;
По сути, '''entered()''' и '''exited()''' – просто обычные функции. Обе получают два параметра, объекты '''actor''' [актер] и '''event''' [событие]. Вначале они выводят эту информацию (что удобно при отладке, для просмотра, какой объект что сгенерировал, но в итоговом приложении не нужно), затем используют унаследованный актером метод '''set_color''', для изменения его цвета. Здесь мы просто определили объекты '''clutter.Color''' на лету. Они принимают значения RGBA, так вот мы установили синий в первом и фиолетовый во втором случае.&lt;br /&gt;
&lt;br /&gt;
===Отцы и дети===&lt;br /&gt;
&lt;br /&gt;
Последняя строка может вызвать удивление: зачем мы возвращаем значение из события? И почему такое странное? Происходит следующее: ''Clutter'' получает сигнал '''event''' на родительском объекте, сцене, которая всегда является реагирующей. В предыдущих уроках нашей серии мы просто соединяли сигналы напрямую от сцены – прошлый раз, например, в обработчике нажатий клавиш. Но родительский объект также просматривает всех своих потомков, пытаясь определить, кто из них ответственен за эффект. Это может быть, например, одинокий прямоугольник в углу или часть в большей группе объектов, являющейся потомком сцены. Когда «виновный» потомок найден, он генерирует сигнал, «всплывающий» вверх к родителю. Это необходимо потому, что если прямоугольник не имеет явного обработчика, его может иметь родительский объект, и щелчок на прямоугольнике будетобрабатываться на уровне группы.&lt;br /&gt;
&lt;br /&gt;
Этот процесс – перехват событий в так называемой «пузырьковой» фазе – действие стандартное, но оно тратит ресурсы, продолжая передавать событие по всем объектам, даже если оно уже обработано. Изящно пресечь это можно, прервав процесс, по типу выхода из цикла – именно это и происходит, когда функция обработки сигнала возвращает значение '''#t'''. И наоборот, если мы решаем, что еще не завершили обработку сигнала (или что-то сделали, но родительский объект все еще нуждается в уведомлении), можно вернуть '''#f''' для продолжения процесса. Таково поведение поумолчанию, но при написании кода почти всегда лучше все объявлять явно: впоследствии это спасает от изрядной головной боли.&lt;br /&gt;
&lt;br /&gt;
===Устраиваем сцену===&lt;br /&gt;
&lt;br /&gt;
Теперь, разобравшись с обработкой сигналов, придумаем несколько генерирующих их объектов, а также сцену, где мы всё разместим.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage=clutter.Stage()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_color(clutter.Color(0,0,0,255))&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_size(200,200)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r=clutter.Rectangle()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.set_size(60,30)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.set_color(clutter.Color(255,0,0,255))&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.set_position(20,20)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.set_reactive(True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код должен быть уже знаком тем, кто следит за нашими уроками. Он создает сцену (главное окно) нашего скрипта и добавляет простой объект-актер – в данном случае, прямоугольник. Метод '''set_reactive()''' сообщает ''Clutter'', что актеру нужно получать события и генерировать сигналы. Это подходит не всегда – фоновой текстуре, например, сигналы ни к чему, даже если она и перехватит пару щелчков – так что здесь требуется явный вызов.&lt;br /&gt;
&lt;br /&gt;
Теперь необходимо просто соединить события с обработчиками, определенными нами ранее, добавить прямоугольник на сцену и показать все, отрисовав в окне:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.connect(‘enter-event’, entered)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.connect(‘leave-event’,exited)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; r.show()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.add(r)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.show_all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Самые наблюдательные из вас могли уже спросить себя: как работает метод '''connect()'''? В конце концов, наши обработчики событий желают знать актера и событие, а все, что мы сделали – это соединили сигналы с соответствующим именем функции (пара скобок после '''entered''' или '''exited''' не нужна – это не вызов!).&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF132_81_1.jpg|300px]] Это не фиолетовый кирпич, а устройство сложного графического интерфейса пользователя.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Так вот, метод '''connect()''' просто хранит соответствие имени события и функции, которую следует вызвать. Когда событие происходит, он вызывает функцию и автоматически передает ей два параметра: себя, (или, по крайней мере, указатель на родительский объект – в нашем случае, прямоугольник), а затем объект-событие. Последнее на самом деле содержит много информации, полезной для обработчика. Кроме типа события, это время (согласно часам ''Clutter''), координаты '''x''' и '''y''' и сцена, где произошло событие, что удобно для многооконных приложений.&lt;br /&gt;
&lt;br /&gt;
Попробуйте. Нам не нужно входить в основной цикл ''Clutter'', чтобы заставить работать обработчики событий нашего скрипта: просто подвигайте мышью в окне над прямоугольником – и увидите, что цвет меняется. Отведите мышь, и он сменит цвет на другой. Ах, эта магия событий…&lt;br /&gt;
&lt;br /&gt;
Возможно, мы пожелаем также перехватывать события щелчков, но вскоре увидим, что существует бездна сигналов, для которых следует создать функции обратного вызова, и все это только для одного объекта-актера!&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Помехи на линии|Содержание=Некоторые люди, в порядке, э-э, конструктивной обратной связи злопыхали, что в приложениях ''Clutter'' анимация выполняется не плавно, а иногда и вовсе не выполняется. Части таких проблем можно избежать, взяв другую версию библиотек ''Clutter'' (особенно если вы используете сборки до версии 1.0), но другая потенциальная проблема коренится не здесь.&lt;br /&gt;
&lt;br /&gt;
Сервер ''X.org X'' не очень-то охотно работает с двумя экземплярами ''GL'' одновременно (что следовало бы учесть в будущем релизе), и если вы запускаете приложение ''Clutter'' вместе с чем-то, также использующим ''GL/GLX'', то не исключены проблемы с производительностью. Сам я, если хочу, чтобы у моих окон колыхались края, просто пью сидр, но понимаю, что многие читатели норовят включить лихой ''Compiz'' ради визуальных эффектов. Почти наверняка это приведет к конфликтам с ''Clutter'', так что хлебните чуть-чуть и отключите ''Compiz'', если не хотите неприятностей в процессе урока.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Решение заключается в том, чтобы ухитриться заставить наш обработчик работать с несколькими событиями. Кстати, он уже работает с несколькими актерами – посмотрите, ведь код ссылается на актера, подающего сигнал, а не на конкретный объект '''r'''. То есть, если мы создадим полторы дюжины прямоугольников, все они будут вести себя одинаково.&lt;br /&gt;
&lt;br /&gt;
Давайте начнем заново, в этот раз с целой стаей кнопок, на которые можно нажимать, но с единственным обработчиком. Теперь несколько проще написать скрипт в ''Kate'' или ''Gedit'' и запустить его как обычное приложение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.remove(r)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; button =[]&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; def handler(actor,event):&lt;br /&gt;
 ... print event,actor&lt;br /&gt;
 ... print event.type.value_nick&lt;br /&gt;
 ... if event.type.value_nick==’enter’:&lt;br /&gt;
 ...   actor.set_color(clutter.Color(0,0,255,255))&lt;br /&gt;
 ... elif event.type.value_nick==’leave’:&lt;br /&gt;
 ...   actor.set_color(clutter.Color(255,0,255,255))&lt;br /&gt;
 ... elif event.type.value_nick==’button­press’:&lt;br /&gt;
 ...   actor.set_color(clutter.Color(255,255,255,255))&lt;br /&gt;
 ... return ‘#t’&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_size(300,200)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; for i in range(4):&lt;br /&gt;
 ... r=clutter.Rectangle()&lt;br /&gt;
 ... r.set_size(50,30)&lt;br /&gt;
 ... r.set_color(clutter.Color(255,0,0,255))&lt;br /&gt;
 ... r.set_position(25+(i*60),150)&lt;br /&gt;
 ... r.set_reactive(True)&lt;br /&gt;
 ... r.connect(‘enter­event’, handler)&lt;br /&gt;
 ... r.connect(‘leave­event’,handler)&lt;br /&gt;
 ... r.connect(‘button­press­event’,handler)&lt;br /&gt;
 ... r.show()&lt;br /&gt;
 ... stage.add(r)&lt;br /&gt;
 ... button.append(r)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF132_82_1.jpg|300px]] Четыре кнопки, созданные роботом! Ну ладно, циклом ''Python'', по любому…|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Здесь есть только два момента, достойных упоминания, поскольку они отличаются от того, что мы уже делали. Во-первых, обработчик теперь реагирует на все события от всех кнопок. Пока примем, что все кнопки ведут себя одинаково (к более изощренному сценарию мы перейдем позже), и все, что нам следует сделать – это сообразить, какое событие обрабатывает функция. Поскольку объект '''event''' автоматически передается в виде параметра, то необходимо просто рассмотреть его свойства (их много, но '''event.name_nick''' короткое и делает код более читабельным). В ''Python'' отсутствует конструкция '''‘case … switch’''' – однако от использования '''if''' и '''elif''' мы здесь потеряем не много.&lt;br /&gt;
&lt;br /&gt;
Во-вторых, мы делаем нечто слегка ненормальное. В цикле '''for''' мы создаем прямоугольник '''r''' и наделяем его свойствами, а затем мы возвращаемся и делаем все по новой – а не затираем ли мы значение в '''r'''? И да, и нет. В самом конце цикла мы добавляем объект-прямоугольник к нашему списку кнопок методом '''append()'''. На самом деле, '''r''' – не сам объект, а лишь его адрес. Прямоугольник будет уничтожен только в том случае, если на него не останется действующих ссылок. В данном случае ссылка есть: она в нашем списке кнопок. При следующем проходе цикла создается еще один прямоугольник, и в '''r''' помещается новый адрес.&lt;br /&gt;
&lt;br /&gt;
Таким образом, каждая кнопка сохраняется, и все они различны. Другой способ сделать это – ссылаться на этапе создания на элементы в списке кнопок; но тогда следует заранее заполнить его корректным числом элементов или добавлять пустые объекты в начале цикла. Этот путь проще, хотя и заставляет делать двойную работу.&lt;br /&gt;
&lt;br /&gt;
===Хорошее поведение===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Наскоро о ''Clutter''|Содержание=Если вы новичок в ''Clutter'', вас, вероятно, выручат предыдущие выпуски этой серии, но приведу краткую сводку.&lt;br /&gt;
&lt;br /&gt;
Сцена ''Clutter'' – эквивалент объекта-окна на экране. Имеются различные методы для установки размера, цвета и подключения событий к сцене. Актер – это любой графический объект, появляющийся на сцене. Графические элементы, включая текстовые объекты и текстуры, порождаемые в ''Clutter'' или приходящие откуда-либо – это актеры. Они могут быть преобразованы в три измерения, и эти трансформации можно анимировать при помощи операций, обрабатываемых ''Clutter''. Обычная процедура – настраиваем сцену, создаем актеров и добавляем их на сцену, а затем делаем что-нибудь крутое.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
''Clutter'' нацелен на создание шикарных графических интерфейсов, так почему бы не сделать так, чтобы кнопки проявлялись и плавно исчезали при перемещении над ними мыши? Это пригодится для медиа-проигрывателя, в котором обычно вы смотрите на экран, но когда хотите чем-то управлять, появляются кнопки. Мы можем легко добавить их при помощи поведений ['''behaviour'''] ''Clutter''. Поведение похоже на сохраненную анимацию, увязанную с событиями временной шкалы. Временная шкала, как мы видели в предыдущих учебниках, это просто механизм прерываний. ''Clutter'' позволяет подключать поведения к объектам, а затем вызывать анимацию, запуская шкалу времени.&lt;br /&gt;
&lt;br /&gt;
Я знаю, о чем вы думаете: не проще ли было использовать метод '''actor.animate()''' для изменения прозрачности объекта? Проще-то проще, да только он не работает. В темных глубинах ''Clutter'' кроется разрушительная ошибка, не позволяющая использовать простой метод '''animate()''' для прозрачности. Если вы все же попытаетесь, то получите несколько предупреждений, хотя код все же будет работать, и любая анимация просто превратится в черноту. Поэтому поведение объектов – наше все.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; timelinefadein = clutter.Timeline(duration=600)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; timelinefadeout = clutter.Timeline(duration=600)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; alpha = clutter.Alpha(timelinefadein, clutter.EASE_IN_SINE)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; behaviour = clutter.BehaviourOpacity(0x0, 0xc0, alpha)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; alpha2 = clutter.Alpha(timelinefadeout, clutter.EASE_OUT_SINE)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; behaviour2 = clutter.BehaviourOpacity(0xc0, 0, alpha2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Мы можем подключать оба поведения к кнопкам по мере их создания и вызывать их из нашего обработчика событий. То есть проявляться и исчезать будут все кнопки, а не только та, над которой завис курсор мыши.&lt;br /&gt;
&lt;br /&gt;
Объекты '''BehaviourOpacity''' принимают три параметра – alpha-объект (контролирующий значения анимации от кадра к кадру) и начальную и конечную непрозрачности. Здесь мы привели их в шестнадцатеричном формате; обычно это лучше, поскольку некоторые операции над альфа-эффектами весьма требовательны к получаемым значениям, а в таком варианте вы будете уверены, что оно преобразуется как 8‑битное целое.&lt;br /&gt;
&lt;br /&gt;
После применения поведения к объекту с помощью '''behavior.apply(actor)''', оно может быть вызвано в любой момент, запуском шкалы времени. Единственная проблема с нашей анимацией сейчас заключается в том, что если очень быстро подносить и убирать курсор мыши, то анимации наложатся друг на друга, вызвав мерцание. Одним из способов исправления этого может быть использование невидимого прямоугольника, накрывающего всю группу кнопок, и применение поведения затухания с его помощью.&lt;br /&gt;
&lt;br /&gt;
Итак, большой вопрос в том, какие чудеса мы извлечем из волшебной корзины ''Python'', чтобы заставить каждую кнопку вести себя по-своему без добавления хрентиллиона строк кода в наш обработчик событий? А позвольте привлечь ваше внимание к экспонату A:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; example=clutter.Rectangle()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; example.set_size(60,20)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; example.MyMadeUpProperty = 8&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; example.MyMadeUpProperty&lt;br /&gt;
 8&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот вам и магия ''Python''. Без всякой мороки с изобретением новых классов и тому подобного, мы можем динамически добавлять свойства к существующим объектам. Итак, хотя актеры ''Clutter'' не имеют соответствующего места для хранения свойства ‘при нажатии кнопки выполнить’, мы просто можем добавить его позднее. Актер '''rectangle''' будет вести себя так же, как обычный прямоугольник, но мы можем приписать к нему любые невероятные выкрутасы, а то и полезные вещи.&lt;br /&gt;
&lt;br /&gt;
===Нажмите кнопку===&lt;br /&gt;
&lt;br /&gt;
Это приводит нас к некоторым дополнительным ценным свойствам ''Python''. Почти все в мире ''Python'' – просто объекты, включая методы и функции. В сущности, метод – всего лишь объект со свойством '''__call__'''. Радоваться тут особо нечему, но зато можно выполнять следующее:&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF132_83_1.jpg|300px]] О, восторг толпы при виде наших появляющихся-исчезающих кнопок, которые парят над видео!|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; dir&lt;br /&gt;
 &amp;lt;built-in function dir&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; dir()&lt;br /&gt;
 [‘__builtins__’, ‘__doc__’, ‘__name__’, ‘__package__’]&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; x=dir&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; x&lt;br /&gt;
 &amp;lt;built-in function dir&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; x()&lt;br /&gt;
 [‘__builtins__’, ‘__doc__’, ‘__name__’, ‘__package__’, ‘x’]&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; x(x)&lt;br /&gt;
 [‘__call__’, ‘__class__’, ‘__cmp__’, ‘__delattr__’, ‘__doc__’, ‘__&lt;br /&gt;
 eq__’, ‘__format__’, ‘__ge__’,&lt;br /&gt;
 ‘__getattribute__’, ‘__gt__’, ‘__ hash__’, ‘__init__’, ‘__le__’, ‘__&lt;br /&gt;
 lt__’, ‘__module__’,&lt;br /&gt;
 ‘__name__’, ‘__ne__’, ‘__new__’, ‘__reduce__’, ‘__reduce_ex__’,&lt;br /&gt;
 ‘__repr__’, ‘__self__’,&lt;br /&gt;
 ‘__setattr__’, ‘__sizeof__’, ‘__str__’, ‘__ subclasshook__’]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Dir''' – встроенная функция ''Python'', с которой мы уже встречались; в основном она используется для интроспекции и сообщает, что есть в объекте. Присваивая переменной '''x''' значение '''dir''' (заметьте, что мы не используем скобки в конце), мы создаем ссылку на эту функцию. В результате '''x''' будет вести себя как '''dir'''. Это действительно '''dir''', просто с другой меткой. Теперь вы можете вызвать '''x''' так же, как вызывается '''dir'''.&lt;br /&gt;
&lt;br /&gt;
Слияние двух этих фрагментов с нашим существующим кодом ''Clutter'' означает, что мы сможем определить методы для выполнения действий, а затем присвоить их новым свойствам, которые добавим к уже созданным объектам-кнопкам. Наш класс-обработчик все еще не требует выполнения чего-то особенного – при щелчке на кнопке он просто вызывает ее свойство-метод ‘'''action'''’ или как мы там пожелаем его назвать. Вам, возможно, кажется, что мы немного увлеклись идеей не писать дополнительный код; тут и правда экономится несколько строк, но на самом деле этот способ обработки объектов реализуется для лучшей читабельности и сопровождаемости участка кода. Функция '''handler()''' – лишь эффективная часть конструкции, или, скажем, коммутатор, соединяющий компоненты вместе при необходимости.&lt;br /&gt;
&lt;br /&gt;
Применив это и позаимствовав код из приложения ''GStreamer'', которое мы писали несколько выпусков назад, можно создать наш собственный простой медиа-плейер с кнопкой паузы, которая исчезает и появляется поверх видео, когда это требуется. Здесь нет места, чтобы привести весь листинг (большую часть его кода мы уже видели), но вы можете найти его (наряду с некоторыми другими) на '''LXFDVD'''.&lt;br /&gt;
&lt;br /&gt;
===Чувак! А где же карта?===&lt;br /&gt;
&lt;br /&gt;
В прошлый раз я сдуру намекнул, что в этом номере мы рассмотрим прекрасное картографическое приложение ''Clutter''. К сожалению, несмотря на то, что такое приложение появилось, оно недостаточно надежно работало со многими версиями зависимых библиотек. Через несколько месяцев мы попробуем вернуться к этому, так что следите за событиями.&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>