Публикации с меткой «development»

Блог python на хабрахабре

Fabric — пара прикладных рецептов

Хабы: Python

Сегодня неожиданно понял, что скрипты — это сила (спустя несколько месяцев использования fabric). На самом деле 30 минут потраченные на написание адекватного сценария избавляют от многих совокупных часов повторения ненужных действий. Для упрощения жизни адептов python'а существует такой прекрасный модуль как fabric. И я хочу поделиться парой кусков своего fab-файла как пример упрощения жизни девелопера.

Это будут функции: «умный» комментатор локальных файлов и git-коммитер.
Читать дальше →

Ростислав Дзинько

wxPython: Gif-анимация и прозрачность

Кратко об анимации в wxPython

Дяденька делает анимацию на wxPython
В wxPython средства для работы с анимацией имеются в виде пакета wx.animate. Пакет довольно нехитрый - всего парочка классов, из которых чаще всего в работе используются 2:

  1. wx.animate.Animation - инкапсулирует параметры анимации, а также поддерживает загрузку анимации из файла. Поддерживает Gif и Ani форматы анимаций.
  2. wx.animate.GifAnimationCtrl - Контрол для отрисовки проигрывания Gif-анимации в графическом интерфейсе приложения.
Последний - очень соблазнительное средство, так как позволяет фактически в несколько строчек добавить в окно готовую анимацию:

...
ag_fname
= r"progress.gif"
ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname, pos=(0, 0), size=(64,64))
ag.GetPlayer().UseBackgroundColour(True)     
ag.Play()

Довольно неплохо. И даже больше ... прозрачность.

Прозрачность

Третья строчка вышеприведенного кода намекает нам, что анимация будет использовать вместо цвета, который в ней установлен прозрачным - фоновый цвет окна. Поговаривают, что на GTK оно так и есть, но я, к сожалению, не имел удовольствия в этом убедится, так как пишу софт, давший вдохновение на написания этой статьи, исключительно для ОС Windows.

Что ж, на Windows оно немножко не совсем так. В случае, если окно, на котором находится контрол имеет установленный цвет фона без дополнительных излишеств - все отлично. Проблемы начинаются тогда, когда на форме вручную через графический контекст рисуется картинка или, чего хуже, форма вообще не прямоугольная, а произвольного формата (к сожалению, так получилось, что мой случай).

В таком случае GifAnimationCtrl только вредит, поскольку на нашей красивой форме вырисовывается анимация с прямоугольным серым (ну, или каким там у вас будет) фоном.

Выход есть

Что же, отбрасываем контрол, берем голую анимацию (благо wx.animate.Animation имеет все средства для получения информации о кадрах, их количестве и "прозрачном" цвете) и рисуем на необходимом окне пользуясь DC (естественно, BufferedDC, чтобы избежать неприятных миганий) и таймером. Все, что нам нужно:
  • wx.Timer
  • wx.animate.Animation (.GetFrameCount(), .GetFrame(), ...)
  • wx.BufferedDC
Единственное, что здесь важно, - метод GetFrame(frame_number) возвращает не wx.Bitmap, который рисуюют, а wx.Image. Поэтому, чтобы получить картинку для рисования, нужно сделать Animation.GetFrame(number).ConvertToBitmap().

При этом, если исходный файл анимации имеет прозрачный цвет, картинке даже не надо делать SetMask(), маска будет создана исходя из кадра и цвета прозрачности. Код приводить не буду, в различных ситуациях он может быть разным, но смысл, думаю, понятен.

Ростислав Дзинько

Wirbel - кина не будет: электричество кончилось

Мой последний пост о языке Wirbel немножко привлек внимание заинтересованных питонщиков, но тут я вынужден всех разочаровать (заголовок этого коротенького поста как бы намекает). 

С момента последней публикации прошло уже больше двух недель, а все мои попытки достучаться до автора по поводу вирбеля так и не увенчались успехом. Последние активные изменения в исходниках датированы 2008 годом, так что, судя по всему, автор, как говорится, "забил" на свое изобретение, и занялся чем-то более полезным с его точки зрения.

Все, что может быть интересно о языке, красноречиво рассказывает предыдущий кратенький обзор. Попытаться написать на вирбеле програмку, которая решает квадратное уравнение у меня получилось, но только тогда, когда я самостоятельно реализовал алгоритм извлечения квадратного корня числа =)

Стоит отметить, что исходники компилятора, которые, как уже упоминалось, имеют в своей основе C++, читать довольно приятно. Немец пишет чуть-ли не идеально структурированно и чисто (даже учитывая глубокое отсутствие у меня практических навыков написания кода на C++, код читался и понимался поразительно легко).

Всем спасибо за внимание.

Ростислав Дзинько

Wirbel - компилируемый Python. Немножко о языке и установке.

Немножко о языке
Ну, не совсем Python, точнее совсем не Python, но синтаксически идентичен, за исключением некоторых ограничений, которые накладывает собой компилируемость в бинарник, а также нескольких новых возможностей. Автором языка и компилятора является немецкий разрбаботчик по имени Матиас Кеттнер, что нетрудно догадаться по картинке.  Вот короткий список характеристик, а заодно и отличий от Python 2.х:
  • print - функция. Поэтому print("Hello, world!")
  • Бинарный код, не требующий рантайма и совместимый с C++
  • Списки типизированы, так что [1, 2, 3, "string"] создать не получится
  • Есть сигнатуры функций, а поэтому def x(a), и def x(a, b) - две разные функции
  • Кортежи изменяемы и могут включать разные типы данных, в отличие от списков: (1, true, "Hi")
  • Строка и символ - разные типы данных. Символ - один байт
  • true, false - зарезервированные слова (в нижнем регистре)
  • import отсутсвует, автор уверяет, что компилятор все сам найдет.
  • Вирбель позволяет писать библиотечки и подключать их из C/C++
  • Ну и, естественно, скорость, как же без этого

Ну, это все можно узнать зайдя на сайт этого чуда. Гораздо же интереснее самому поставить и попробовать.

Вот как я его устанавливал на Ubuntu 11.10

Качаем со странички загрузки исходник. К слову, сам компилятор Вирбеля написан на С++ (вспоминаем, что СPython написан на С). Компиляция и сборка из исходников процесс не новый, а всем хорошо известный.
./configure
После этого он матюкается, что ему каких-то пакетов не хватает - доставляем.
./make
Тут он минуты две думал, плевался в консоль текстом и, в результате,
извините, мол, две ошибки... Ну что же, пишем автору (какой он нехороший человек, что его компилятор не компилируется на моей Ubuntu 11.10 Alpha 1) об ошибке. Но ждать надоело уже через минут пять, поэтому я полез таки в исходники и пофиксил две мелкие ошибки: в файлах Type.cc и Location.cc не хватало #include <cstdio>, а в baustones/httpd/HTTPRequest.h - строчки #include <stdint.h>, чтобы подключить определения целочисленных типов данных.
sudo make install

делает все необходимое, чтобы я наконец-то получил возможность пользоваться этим компилятором.

И наконец - первая программа

Не буду сильно оригинальничать - сделает обычный "Привет, мир!". Для этого создадим уютную папочку, зходим в нее, создаем текстовый файлик с расширением *.wfor (в моем случае wtest.wfor) и наполняем его единственной строчкой:
print("Hello, world!")
После сохранения файла выполняем компиляцию:
wic wtest.wfor -o wtest
Пара секунд размышлений и мы получаем исполняемый файл. Пока есть небольшой минус - такая мелкая программа занимает 93кБ, но, думаю, это некритично.

Надеюсь на to be continued...

Ростислав Дзинько

Как перейти c PHP на Python


Вступление
На форуме python.su, в жизни которого я активно участвую начали появляться темы о том, как перейти с php на python. Естественно, здесь я буду рассматривать только веб-разработку.
В этой статье я бы хотел рязъяснить некоторые моменты, чтобы php разработчикам, которые все-таки решили начинать разрабатывать веб-приложения на python было понятно, что да как.

Как работает php?
Для начала, примем во внимание, что PHP изначально задумывался и разрабатывался исключительно как язык для веб-разработки, и в 99.9% случаев для этого и используется (можно, конечно, писать и GUI-приложения, например, для этого есть GTK-биндинги).

Говоря о том, как работает PHP? я имею в виду то, как принято в большинстве случаев разрабfтывать веб-приложения на PHP. Я не буду углублятся в устройство интерпретатора, расширения, MINT, и т.д. Для пущей простоты примем интерпретатор PHP за некую отдельную сущность. В общем случае, все происходит примерно так:
То есть в самом простом случае, мы создаем html страницу, внутри которой находятся блоки PHP-кода, обрабатывающие запрос и генерирующие динамическое содержимое страницы. Первое, что PHP-программисты при переходе на python обычно делают (по крайней мере те, которые пользуются веб-сервером Apache):
  1. Ставят на Apache mod_python.
  2. Конфигурят директорию в httpd.conf.
  3. Добавляют туда скрипт с содержимым: print "Hello, world!".
  4. Запускают браузер и указывают URL якобы скрипта, например: "localhost/hello.py".
Такое - не работает.

Так что же насчет Python?
Опять же таки вернемся к истории. Исторически и практически Python является языком общего назначения, то есть не нацелен на какую-либо узкую область решения задач. Поэтому он не обладает встроенными средствами работы в веб-среде, как, например, работа с http-сессиями (в отличие от php). Поэтому вариант "создать страничку -> добавить блоки python-кода внутрь" не проканает.

Как разрабатываются веб-приложения на Python?

В отличии от PHP в Python нет стандартных механизмов работы с веб окружением (куки, сессия, и т.д.). Каждый фреймворк и подход имеют свои библиотеки для работы с этими вещами.

Вариант 1. Почти как в PHP. Называется это Python server pages - проект умер в зародыше, а кто так пишет подвергается в Python-сообществе остракизму. Возможен благодаря mod_python. Более детально можно почитать здесь.

Вариант 2. WSGI (web server gateway interface). Являет собой стандарт взаимодейтсвия веб-сервера и веб-приложения Python. В качестве веб-сервера можно использовать Apache с mod_wsgi, nginx с uWsgi, CherryPy и другие. На базе этого стандарта работают многие фреймворки для веб-разработки, в том числе и популярнейший из них - Django. В общем случае, для того, чтобы разрабатывать веб приложения, вам нужно обратится к документации к одному из этих фреймворков. Вот несколько из них:
Вариант 3. Неблокирующий веб-сервер и фреймворк к нему, которые написаны на Python. Имеют свои специфические API. Примеры:
  • Tornado
  • Zope3
  • Twisted (это скорее средство построения фреймворков и серверов)
Данные фреймворки написаны в стиле событийно-ориентированного программирования.

От себя
От себя порекомендую для начала разработки веб-приложений на Python обратится к одному из простых фреймворков, так называемых, микрофреймворков, например, Flask.

Полезные ссылки

Ростислав Дзинько

Встроенный Django сервер тормозит на Windows 7


Столкнулся с такой вот проблемой, что встроенный сервер Django очень долго обрабатывает запросы в операционной системе Windows 7. Ситуация примерно такая. Запускаем сервер:
python ./manage.py runserver 127.0.0.1:3333
Заходим на сайт:
http://localhost:3333/
После этого получаем контент только после долгой задержки, что не очень приятно в процессе активной разработки или тестирования сайта. Оказывается, проблема возникает из-за, кто бы подумал, IPv6, так как понятие localhost в контексте наличия разных протоколов уже не такое однозначное. Поэтому делаем 2 шага:

1. Раскомментируем строчки (у кого они не раскомментированы в C:/Windows/System32/drivers/etc/hosts)
127.0.0.1 localhost
#::1 localhost
2. Заходим на сайт не через localhost, а по 127.0.0.1.

Удачного джангирования!

Ростислав Дзинько

Статика и девелоперский сервер на большом Django-проекте


Что есть девелоперский сервер?
Хотел бы поделиться одним своим наблюдением насчет работы со статикой сервера django, который из коробки, и, собственно, не рекомендуемый для использования в production-среде. Для простоты использования статических файлов, то бишь всяких там стилей, картинок и клиентских скриптов, разработчики django-фреймворка втулили некое представление:
django.views.static.serve
Наверное большиство django-программистов используют эту вещь в работе, как и девелоперский сервер:
python ./manage.py runserver :
Более того, по статистике djangosites 1.2% пользователей не заморачиваются со всякими там инжиниксами, и апачами, и публикуют свои приложение таким вот нехитрым способом.

Проблемка
При этом всем, наверное, немногие сталкивались с тем, даже в довольно крупных проектах, что девелоперский сервер зависает на каждом втором-третьем запросе, что не просто раздражает, а делает разработку практически невозможной. С одной из причин такого зависания я недавно столкнулся. А дело было в статических ресурсах, которые должны были отдаваться клиенту, но по объективным причинам не отдавалий, то есть на каждый запрос по требованию картинки, скрипта, и т.д. приходил ответ 404. Так вот, если таких ресурсов накопится 20-30, сервер виснет уже на 2-3 запросе.

Вместо заключения
Причина этого кроется в том, что над такими проблемами с сервером никто не заморачивается, так как для работы в production-среде он не предназначен, и уж тем более для обслуживания статики.

Ростислав Дзинько

Проблемы с локализацией кнопок диалогового окна wx.MessageDialog

Э-э-х, где же ты, кросс-платформенность?

Класс wx.MessageDialog имеет разную реализацию на разных операционных системах. Собственно на операционных системах GNU/Linux этой проблемы вовсе нет, так как это диалоговое окно реализовано средствами wxWidgets, и перевод кнопок осуществляется через стандартный механизм интернационализации wxPython. Совсем по другому обстоят дела на ОС семейства Windows.

wx.MessageDialog на ОС Windows

Для ОС Windows данное диалоговое окно реализовано средствами операционной системы (лень, видать было сделать по-другому). Соответственно, имеем вызов функции MessageBox из всеми любимого нами Windows API. А по сему вся интернационализация производится также средствами операционной системы, и влезть в этот процесс мы никак не можем, а окна, которые наполовину на одном языке, наполовину на другом совсем уж не красят приложение и его автора.

Свет в конце тоннеля

Да, он есть. Выход заключается в написании собственного диалога на базе wx.Dialog. Пример можно посмотреть в wxDemo. Хорошо то, что при замене старого диалога новым не приходится переписывать программный код взаимодействия с ним. Вы также можете использовать методы Show() и ShowModal(), а также идентификаторы кнопок, такие как wx.ID_OK, wx.ID_NO, и т.д.

Совет на будущее (в том числе и себе)

Так, что если ваша программа будет нуждаться в локализации, о wx.MessageDialog советую забыть вообще, и делать свои диалоги на базе wx.Dialog.

Ростислав Дзинько

Python: как программно переключить раскладку клавиатуры в Windows

Исследовав данный вопрос, я обнаружил, что Python не имеет средств из коробки для решения этой задачи. Соответственно, задача должна решаться для каждой ОС своим путем. Данное решение было найдено мной для ОС Windows XP +.

Панацея - Win API
Для того, чтобы выполнить задачу необходимо установить дополнительную библиотеку pywin32, которая предоставляет доступ к функциям Windows API из Python. Из этой библиотечки нам понадобится модуль win32api.
>>> import win32api
Исследовав его содержимое можно увидеть, что для работы с раскладкой клавиатуры есть несколько функций и одно системное сообщение Windows - WM_INPUTLANGCHANGE:
  • GetKeyboardLayout
  • GetKeyboardLayoutList
  • LoadKeyboardLayout
В данном случае для нас важна именно последняя функция - LoadKeyboardLayout. Данная функция загружает новую раскладку (если она еще не загружена) и предпринимает после этого еще какие-то действия; принимает в качестве аргументов два параметра:
  1. строка с идентификатором раскладки.
  2. действие
Более подробно о их возможных значениях можно почитать в MSDN. Итак, нам важны две вещи:
  1. Получить идентификатор раскладки.
  2. Вторым параметром передать действие переключения на загруженную раскладку.
Первый параметр мы можем с легкостью получить из реестра по пути: HKEY_CURRENT_USER/Keyboard Layout/Preload. Итак, выберем переключение на русский язык. В реестре видим примерно следующее:

Значение записи реестра как раз и будет нужным идентификатором раскладки.
Итак, все, что надо сделать:
>>> import win32api
>>> win32api.LoadKeyboardLayout("00000419",1)

Ростислав Дзинько

Переходим на Python 3. Новый print.

С недавнего времени решил начинать осваивать Python 3, а свои наблюдения и опыт изучения писать в блог, да так, чтобы и самому структурировать новые знания и читателям было интересно. Так что милости прошу к первой заметке о новой реализации стандартного вывода.

Первое знакомство
Наверное, первое, что бросается в глаза при переходе на Python 3, это новая реализация механизма стандартного вывода - оператор print был заменен на функцию print(). Зачем? Такое вот, казалось бы, незначительное, от нечего делать, изменение. Что ж, следует исследовать проблему поподробнее.

История
Нарекания на реализацию вывода как оператора print не один раз возникали и бурно обсуждались в списке рассылке (Python-dev mailing list), и вылились все они в один единый документ - PEP3105. В данном документе сразу же можно увидеть список недостатков оператора print. Изложу их вкратце в вольном переводе и своих комментариях в скобках:
  1. print - единственная операция уровня приложения, под которую выделен оператор, и, в принципе он там не нужен (сильно, так сказать, много чести для операции вывода).
  2. На некотором этапе разработки приложение возникает необходимость в замене вывода в стандартный поток на что-нибудь более умное, вроде лога. Сейчас же приходится обходится другими средствами, доходит и до использования >>stream (как по мне, то это никак не Pythonic-way).
  3. На днный момент нет удобного пути вывода нескольких объектов с разделителем отличным от пробела.
По этому поводу в Python 3 оператор print был заменен функцией print(). На самом деле очень удобно. Приведу несколько иллюстраций в сравнении на Python 2.6 и Python 3.

Практические примеры
Пример 1. Вывод одного объекта.

Python 2.6
>>> x = 1
>>> print x
1
Python 3.1.1
>>> x = 1
>>> print(x)
1
Интересный пример. Расхвалили новый print, а тут на тебе - ни одного плюса, только один минус - нужно тянуться к скобкам на клавиатуре =). Впрочем, у кого есть IDE с настроенной горячей клавишей на вставку вывода (например, TextMate), особо не почувствует.

Пример 2. Вывод трех объектов.

Python 2.6
>>> x1 = 1
>>> x2 = 2
>>> x3 = 3
>>> print x1, x2, x3
1 2 3
Python 3.1.1
>>> x1 = 1
>>> x2 = 2
>>> x3 = 3
>>> print(x1, x2, x3)
1 2 3
Так, что у нас здесь. Вроде бы никаких плюсов опять.

Пример 3. Вывод трех объектов с разделителем ";".


Python 2.6
>>> print x1, ';', x2, ';', x3
1 ; 2 ; 3
Коротко, но как-то не совсем ожидаемый результат. Между выводимым значением и точкой с запятой стоят пробелы. Надо что-то менять. Например, так:
>>> print '%s;%s;%s' % (x1, x2, x3)
1;2;3
Опять не то. А что если параметров будет 10? Не строчить же нам 10 %s-ов. Давайте так:
>>> print ('%s;'*3)[:-1] % (x1, x2, x3)
1;2;3
Python 3.1.1
>>> print(x1, x2, x3, sep=';')
1;2;3
Что же мы видим здесь? Задача решается с помощью как старого подхода, так и нового. Но, согласитель, оператор справляется с задачей как-то уж очень некрасиво, да и мозги надо хоть как-то включить, чтоб такое вывести, не то что просто задать параметр sep.

Пример 3. Решить задачу из примера 2, только без перевода строки в конце.
Вот тут-вот оператор print вообще дает сбой. Он этого попросту не умеет, а иногда для удобства такое нужно (самому несколько раз требовалось). Что ж, в Python 2.6 можно реализовать так:
Python 2.6
>>> import sys
>>> sys.stdout.write(('%s;'*3)[:-1] % (x1, x2, x3))
1;2;3>>>
Python 3.1.1
>>> print(x1, x2, x3, sep=';', end='')
1;2;3>>>
А это выглядит уже вообще не прикольно. Мало того, что задачу решили не через print, так еще нужно импортировать дополнительный модуль, и чего-то там делать, тогда как по идее задача должна решаться через оператор print, так как это задача стандартного вывода. Гораздо веселее, как видите, это выглядит в Python 3 - просто еще один параметр.

Ладно, не буду уже приводить пример с перенаправлением вывода в поток или файл (ну, в конечном счете, для Python это одно и тоже - file-like object), так как в Python 2.6, по сравнении с Python 3 это покажется действительно страшным зрелищем.

Подведем итоги
Надеюсь, я убедил вас, что замечательная функция print, пойдет на пользу как языку, так и его разработчикам (себя я убедил =)). Итак, что мы имеем? А имеем мы функцию print:
def print(*args, sep=' ', end='\n', file=sys.stdout)
  • *args - выводимые объекты
  • sep - разделитель между выводимыми значениями (по умолчанию - пробел)
  • end - символ, которым заканчивается вывод (по умолчанию - символ новой строки)
  • file - file-like объект, в который мы можем перенаправить вывод, который по умолчанию производится в sys.stdout
Не попадайтесь
Заметил один замечательный побочный эффект работы с разными версиями Python, связанный с новым print. Если в Python 3 вы по ошибке напишите
>>> print x1, x2, x3
получите синтаксическую ошибку. Если же в Python 2.x, напишете
>>> print(x1, x2, x3)
(1, 2, 3)
получите вывод кортежа. Эффект не критичный, но все-же присутствует.




Ростислав Дзинько

Как узнать параметры процессора в Windows XP с помощью Python

Собственно, я нашел два способа, как это сделать.

Способ 1 - через реестр
Информацию о вашем CPU можно получить, прочитав ветку HKEY_LOCAL_MACHINE\HARDWARE\
\DESCRIPTION\\System\\CentralProcessor\\0. Вот как это выглядит:








Получить доступ к реєєстру в Python очень легко с помощью модуля _winreg, который входит в стандартную библиотеку. Вот, что нужно сделать, чтобы получить тактовую частоту процессора:

import _winreg
handle = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, '\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0')
value = _winreg.QueryValueEx(handle, '~MHz')

Способ 2 - библиотека WMI
Библиотека WMI (Windows Measurement Instruments), написанная Тимом Голденом, позволяет решить эту задачу гораздо быстрее.

>>> import wmi
>>> c = wmi.WMI()
>>> c.Win32_Processor()[0].MaxClockSpeed
2812
>>> c.Win32_Processor()[0].NumberOfCores
2

На самом деле то значение, которое мы получаем в Win32_Processor()[0] - это объект класса, спецификацию которого можно почитать, обратившись к MSDN. Таким образом, получаем возможность получить гораздо больше информации.

Ростислав Дзинько

Скрещиваем pywinauto и py2exe

А начиналось все с GUI-приложения
Как-то понадобилось мне в приложении делать автоматизированную работу с внешними программами, а конкретно с Adobe Reader. Задача в следующем. При выполнении поиска в Python-приложении (то есть, вводим текст в wxPython GUI) - открывать PDF-файл с помощью Adobe Reader, да не просто открывать, а так, чтобы в строке поиска уже было введено слово, по которому ищется информация, а сам PDF-документ был открыт на первом найденном результате. Ко всему прочему приложение распространяется под Windows-платформы, исполняемые файлы создаются с помощью py2exe.

Но потребовалась некоторая автоматизация действий пользователя
Для решения этой задачи был выбран pywinauto - замечательная библиотека для тестирования GUI-приложений. И хотя в данном случае никакого тестирования нет, с автоматизацией она тоже справляется на ура.

И тут в чудесный мир Python врывается exe-формат
Все отлично отрабатывает, если запускать python скрипт. Проблемы возникают в случае, когда запускается это же приложение собранное с помощью py2exe.

Спасибо py2exe за его чудесную функцию ведения лога. В логе можно увидеть примерно следующее:

Traceback (most recent call last):
File "autorun.py", line 3, in
from gui.wxmain import SplashWindow
File "zipextimporter.pyc", line 82, in load_module
File "gui\wxmain.pyc", line 11, in
Splash window
File "zipextimporter.pyc", line 82, in load_module
File "pywinauto\__init__.pyc", line 28, in
File "zipextimporter.pyc", line 82, in load_module
File "pywinauto\findwindows.pyc", line 37, in
File "zipextimporter.pyc", line 82, in load_module
File "pywinauto\controls\__init__.pyc", line 33, in
File "zipextimporter.pyc", line 82, in load_module
File "pywinauto\controls\win32_controls.pyc", line 37, in
File "zipextimporter.pyc", line 82, in load_module
File "pywinauto\tests\__init__.pyc", line 153, in
File "pywinauto\tests\__init__.pyc", line 137, in __init_tests
ImportError: No module named allcontrols

Решаем проблему
Как видим, существует проблема с импортами в тестах. Проблема решается очень просто. Заходим в c:\Python<версия>\Lib\site-packages\pywinauto\tests\, открываем замечательный файлик __init__.py и комментируем все строки, которые хоть каким-то боком что-то импортируем (с целью экономии глаз и нервов читателя, полный код модуля приводить не буду). Собираем еще раз исполняемый exe-файл, и все работает.

P.S
Проблема у меня возникла в pywinauto при версии Python 2.6. Возможно, в других версиях такой проблемы и не будет.

Ростислав Дзинько

wx.PaintDC не перерисовывает картинку

Очень интересный эффект, а точнее ошибка, получилась у меня при отрисовке на форме (wx.Frame) с помощью wx.PaintDC. Вот код события wx.EVT_PAINT, который использовался сначала:

def on_paint(self, evt):
self.dc = wx.PaintDC(self)
self.dc.DrawBitmap(self.background, 0,0, True)

Как вы уже, наверное догадались данные манипуляции ведутся с целью отрисовки фона окна, а точнее само окно в форме картинки. Пример можно подсмотреть в wx.Demo -> Miscellaneous -> ShapedWindow. Так вот, такой код приводит к тому, что, если деактивировать окно (произойдет событие ex.EVT_ACTIVATE), и потом опять активировать (это же событие), то контролы внутри окна не отрисуются. Теперь посмотрим на код, который работает правильно:

def on_paint(self, evt):
dc = wx.PaintDC(self)
dc.DrawBitmap(self.background, 0,0, True)

Как видите, проблема решилась тем, что мы не делаем контекст атрибутом окна. Почему так? Хороший вопрос, и ответ на него пока не знаю, не углублялся, так как особо нет времени. Но если кто знает ответ на этот вопрос, милости прошу в комментарии.

Ростислав Дзинько

Подводный камень позиционирования окон в wxPython

Представим себе окно (wx.Frame), которое нужно разместить на екране согласно некторому алгоритму, например, отцентрировать. Что мы делаем?

class MyFrame(wx.Frame):
...
def __init__(self):
...
ds = wx.DisplaySize()
self.SetPosition((ds[0] / 2 - self.Size[0] / 2,
ds[1] / 2 - self.Size[1] / 2))
...

Предположим, что метод __init__ содержит еще массу программного кода дял инициализации окна. В таком случае, логично предположить, что вышеописанная операция должна быть описана после всех манипуляций с размерами окна.

Часто такие операции происходят неявно, и, следственно, окно позиционируется совершенно неправильно, и об этом следует всегда помнить. Примером такой неявной смены размеров окна может быть, скажем установка сайзера (wx.Sizer):

self.SetSizer(self.main_sizer)
self.Fit()

В этом случае окно "подтянет" свои размеры под сайзер и, соответственно, позиционирование пройдет неправильно.

Ростислав Дзинько

Особенности промышленного копирования файлов в Python

Столкнулся с задачей копирования файлов в Python. Задача состояла в том, чтобы копировать полностью структуру папок из одного места в другое, запускать программу, а потом удалять все содержимое, которое было скопировано.

Первые шаги

Первое что пришло в голову - использовать для задачи os.walk(). Данная функция делает рекурсивный проход по указаному пути, принимая параметром папку в качестве корня дерева, которое необходимо обойти. Стоит заметить, что здесь важным параметром является topdown, в том случае если вы на каждом шаге хотите предпринимать некие действия (в моем случае - это прогресс бар, который выступает индикатором прохождения процесса корпирвоания) . Это необязательный параметр, который принимает булевое значение, определяющее порядок обхода. Для копирования решил использовать функцию copy модуля shutil, который входит в стандартную библиотеку python. Вуаля, все работает. Удаляем файлы после запуска программы, аналогично обходя дерево только уже в той папке, в которую были скопированы файлы.

Небольшая проблемка

Зачем огород городился? Особенностью данной задачи является то, что файлы необходимо копировать из оптического носителя (CD/DVD-диска). Копировать на жесткий диск необходимо, поскольку некоторые приложения для своей работы используют временые файлы, а также пишут данные в файлы настроект. В чем отличие? А отличие в том, что при ипользовании функции copy файлы копируются вместе с битами доступа, а так как источником является оптический диск, то они обозначаются как "только для чтения".

Решение

Решение довольно простое - использовать функцию copyfile из этого же модуля, который не сохраняет биты доступа. Таким образом файлы с легкостью могут быть удалены.

Знание - сила

Модуль shutils обладает также достаточно удобными и полезными функциями массовой обработки файлов, как, например, copytree, или rmtree, которые позволяют отказаться от использования os.walk(). В данном случае copytree использовать не получится, так как нельзя вставить дополнительный код на этапе копирования отдельного файла, а rmtree очень даже хорошо сокращает количество кода.

Выводы

Знание - сила. Перед решением задачи делаем более глубокое исследование готовых решений и инструментов и не полагаемся на уже приобретенные знания.

Метки

.net .NET C# .sort 1.2 2009 2010 404 error admin ajax amazon analytics and apache api archlinux asp.net async asynchronous autocomplete bash blender blog blogengine blogs book bootstrap bot bpython buildout byteflow bzr C c plus plus C++ cache cbv Chaco checkio chrome ci ckeditor class based views clojure closure cms cms с удобной админкой code coding style collectd COM comet competition conference ConfigParser contest Context continuous integration CouchDB coverage CppCMS cpyext cpython crud csrf CSS ctypes curl custom model fields cx_freeze cython database db dbm dbqueries debian debug debugging decorator decorators deploy deployment descriptor design dev devconf developers development diveintopython Django django 1.2 django 1.3 django advent django framework django template django trunk django weblog django-admin-tools django-cms django-compressor django-hosts django-piston django-registration django-sphinx django.admin djangoadvent djangocms djangodash doc documentation drupal e-legion eclipse EGit emacs encoding Enthought epoll erlang event exception ExtJS fabric facebook fastcgi finaloption fixtures fonts forms formset fp framework freebsd freeswitch fs2web ftp fun funcparserlib functional gae gamin gandi generic views gettext gevent gil git github gitosis Google Google App Engine google picasa Google Translate google wave Google Web Toolkit grab grablab greenlet gtd gui haskell hg hgshelve highlighter host hosting how-to howto html html5lib Hudson humor i18n icfpc ide idiomatic image-scripting improvements Internet interpreter ipython ironpython izmenimsya.ru jabber java javascript jenkins jetbrains JIT job jquery json jstree jython kde kiev kiyv kyivpy l10n ldap library libs Life Links linux Linux & Unix LLVM logging logs lxml Mac OS X magic mail markdown Matplotlib Mayavi maybe mediavirus meetup memcache Memcached memory messages metaclass middleware migration mikrotik mkd model models mod_python mod_wsgi mongodb monitoring mptt musicmans.ru musicx mvc my-projects mysql netCDF networkx newforms newforms-admin news nginx Nhibernate nix nose NoSQL numpy oop open source OpenID openoffice opster optimization oracle orm os pagination parsing path patterns pdf PDF-принтер PEP PEP8 performance performance optimization perl personality photo php picture-driven computing PIL pinax pingback pip plasma plone plugin plugins postgresql programming progress bar psycopg2 py2exe pybb pybbm pycamp pycharm pycon pycow pycurl pydev pygtk pylons PyNGL pypy pyqt PyQt4 pyrad pyramid PySide Python Python 2.5 python 2.7 python 3 python c api python speed python-mssql python3 pywinauto Qt Qt4 queue rabbitmq radius raw sql re redis redsolution redsolution cms regexp regular expressions release repoze.bfg RequestContext reusable apps robokassa rss ru ruby ruby-on-rails sample satchmo scalability SciPy scraping screencast search selenium self.error seo server setattr settings setuptools shell sikuli sms snippet socket.io software sorting south sphinx spider sql sqlalchemy sqlite ssh startup step-by-step subdomain subversion svn SyntaxHighlighter system tags tdd tddspry teh drama template templates templatetags test testing thinkpad threading threads tips tips and tricks tools tornadio tornado tornado server tricks tutorial tweepy twisted twitter typography uapycon Ubuntu ucsvlog uml Uncategorized unicode unit test unit testing UnitTest Unladen Swallow upload urllib urls utf-8 uwsgi validation vcs versioning video vim virtualenv Visual Studio vkontakte voip wave web web-devel web-services web-разработка webdev webfaction webkit webpy websockets webtest widget widgets Win API windows Wirbel work wrapper wsgi wxPython wxWidgets wysiwyg xapian xml xmonad xmpp xpath yandex youtube zip zomg zope [cdata[cbv]] [cdata[ci]] [cdata[class based views]] [cdata[continuous integration]] [cdata[django framework]] [cdata[django-sphinx]] [cdata[django]] [cdata[nginx]] [cdata[python]] [cdata[virtualenv]] [cdata[программирование]] автоматизация администрирование администрирование django админка алгоритмы архитектура атрибуты базы данных Без рубрики безопасность библиотеки блоге бот веб-разработка видео Визуализация данных вконтакте Все записи гвидо ван россум граббер графика графы декоратор декораторы дескриптор дескрипторы документация заметки игра жизнь идея интересное киев Клиентам книги конференция личное математика метаклассы модели модули монады морфология мысли невозможное новости о облачные вычисления обо мне Обработка данных оптимизация оптимизация кода Основная лента основы парсинг парсинг сайтов перевод песочница Питон поебень поиск правила кодирования программирование Проектирование производительность работа рабочее размышлизмы Разное разработка разработка приложений разработки регулярные выражения сайт событие события ссылки статьи тестирование тесты Тюмень убунтариум фигня философия формы форум Хабрахабр хакинг хостинг шаблоны шаблоны проектирования эксперимент Эксперименты юмор я пиарюсь Яндекс