Архив рубрики: Python

2.x/stdlib — parser. Документация

parser — Доступ к распарсенным деревьям Python

Модуль parser предоставляет интерфейс для внутреннего парсера Python и компилятора байт-кода. Основная цель этого интерфейса — позволить коду на Python редактировать дерево выражений Python и создавать из него выполняемый код. Это лучше чем пытаться разобрать и модифицировать произвольный фрагмент кода на Python because parsing is performed in a manner identical to the code forming the application. Кроме того, это быстрее.
Note

 

Начиная с 2.5, более удобно влезть в этапы генерации Abstract Syntax Tree (AST) и компиляции, при помощи подуля ast.
Модуль parser экспортирует имена, документированные тут, заменяя “st” на “ast”; это наследие ещё тех времён, когда не было другого AST и никак не связано с AST из Python 2.5. Кроме того, это ещё и причина того, что именованные аргументы функций называются ast, а не st. Функции “ast” убраны в Python 3.
Есть несколько вещей, которые надо иметь ввиду при работе с этим модулем. Данная документация не является руководством по редактированию распарсенного дерева кода Python, но некоторые примеры использования модуля parser Вы тут встретите.
Особенно важно хорошее понимание обработки грамматики Python внутренним парсером. Более подробная информация о синтаксисе языка находится в The Python Language Reference. Сам парсер создаётся из грамматических спецификаций, определённых в файлеGrammar/Grammar в стандартной постановке Python. Распарсенные деревья сохранённые в объектах ST, создаваемых этим модулем, являются актуальным выводом внутреннего парсера, когда они создаются функциями expr() или suite(), описанными ниже. Объекты ST создаваемые функцией sequence2st() имеют схожую структуру. Имейте ввиду, что значения последовательностей, которые “корректны” могут отличаться для разных версий Python, если отличается формальная грамматика языка. Однако, перенос кода из одной версии Python в другую всегда будет создавать корректное распарсенное дерево для данной
версии, с тем лишь ограничением, что переход на более старую версию не будет поддерживать более новые конструкции языка. Распарсенные деревья, обычно, не совместимы меду разными версиями, тогда как для исходного кода гарантируется forward-compatible.
Каждый элемент последовательности, возвращаемый функциями st2list() или st2tuple() имеет простую форму. Последоватльность, представляющая нетерминальные элементы грамматики всегда имеет длину больше одного. Первый элементом является число, которое идентифицирует выражение грамматики. Эти числа имеют символические имена, определённые в заголовочном файле CInclude/graminit.h и в модуле Python symbol. Каждый дополнительные элемент последовательности представляет компонент выражения, который был распознан в исходной строке: они всегда являются последовательносями той же формы, что и родительская последовательность. Важный аспект этой структуры, который надо иметь ввиду, что ключевые слова, используемые для идентификации типа родительского узла, такое как if в if_stmt, включается в узел дерева без дополнительной трактовки. Например, ключевое слово if представляется кортежем (1, 'if'), где 1 — числовое значение, ассоциированное с токеном NAME, который также включает переменные и функции, определённые пользователем. В альтернативной возвращаемой форме, когда требуется информация о номере строки, тот же самый токен может быть представлен как (1, 'if', 12), где 12 — номер строки, в которой был найден терминальный символ.
Терминальные элементы представляются похожим образом, но без дочерних элементов и без дополнений в виде исходного кода, который был идентифицирован. Опять же смотрите выше пример для ключевого слова if. Различные типы терминальных символов определены в заголовочном файле C Include/token.h и модуле Python token.
Объекты ST не требуются для поддержки функциональности этого модуля, но они используются для трёх целей: чтобы позволить приложению снизить стоимость обработки сложных распарсенных деревьев, чтобы предоставить представление распарсенного дерева, которое потребляет меньше памяти, чем представление при помощи списков или кортежей, и для того, чтобы проще сождавать дополнительные модули на С, которые манипулируют этими деревьями. Простой класс обёртка может быть создан в Python для того, чтобы скрыть использ

Отправка email при помощи python

В этом сообщении будет показано как, используя
Python, отправлять email-сообщения, причём будет показано как добавить файл-вложение в письмо.

Пример 1.

import smtplib   
from email.mime.text import MIMEText
me = 'admin@mail.ru'
you = 'kot_smit@mail.ru'
smtp_server = 'smtp.mail.ru'
msg = MIMEText('Message e-mail')
msg['Subject'] = 'The contents of '
msg['From'] = me
msg['To'] = you
s = smtplib.SMTP(smtp_server)
s.sendmail(me, [you], msg.as_string())
s.quit()
 
  

Если нужно использовать свой smtp-сервер, то в строке

s = smtplib.SMTP(smtp_server)

переменную smtp_server указывать просто не надо. таким образом строка преобретает вид —

s = smtplib.SMTP()

затем нужно добавить строку

s.connect()
 
 

Пример 2.
Отправка письма с вложением, используется smpt.yandex.ru

from smtplib import SMTP_SSL
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Encoders
import os

filepath = "/path/to/file"
basename = os.path.basename(filepath)
address = "name@server"

# Compose attachment
part = MIMEBase('application', "octet-stream")
part.set_payload(open(filepath,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % basename)

# Compose message
msg = MIMEMultipart()
msg['From'] = address
msg['To'] = address
msg.attach(part)

# Send mail
smtp = SMTP_SSL()
smtp.connect('smtp.yandex.ru')
smtp.login(address, 'password')
smtp.sendmail(address, address, msg.as_string())
smtp.quit()


Автор: D1VER
Дата публикации: 2013-09-01T22:32:00.001-07:00

Определение главного потока приложения

В многопоточной программе все потоки равны, но один всё же несколько выделяется. Это — главный поток.

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

Иногда нужно знать, код исполняется в главном потоке или нет. Например, работать с UNIX сигналами можно только из главного потока. Различные GUI библиотеки часто тоже хотят выполняться непременно в главном потоке и никаком другом.

Если мы пишем приложение, то всегда можно придумать тот или иной способ узнать главный поток. Например, при старте, когда других потоков ещё нет, узнать идентификатор потока через threading.get_ident() и запомнить его где-нибудь.

Когда создаём библиотеку такой способ не всегда подходит. А в самом питоне нет официального способа определить, главный поток это или нет.

Зато работают пара хаков.

Тест на главность потока:

isinstance(threading.current_thread(), threading._MainThread)

Идентификатор главного потока:

threading._shutdown.__self__.ident

Используются непубличные механизмы, но это всё же лучше чем ничего.

P.S. В Python 3.4 появится функция threading.main_thread(), которая возвращает объект главного потока. А до тех пор пользуемся хаками.

Автор: Andrew Svetlov

Celery, начало работы

Данное сообщение является одним из многих, которые будут написаны в процессе изучения Celery.

Celery — «distributed task queue». Это распределенная асинхронная очередь заданий, которая обладает широким функционалом.

Celery умеет:

  • Выполнять задания асинхронно или синхронно
  • Выполнять периодические задания(умная замена crond)
  • Выполнять отложенные задания
  • Распределенное выполнение (может быть запущен на N серверах)
  • В пределах одного worker'а возможно конкурентное выполнение нескольких задач(одновременно)
  • Выполнять задание повторно, если вылез exception
  • Ограничивать количество заданий в единицу времени(rate limit, для задания или глобально)
  • Routing заданий(какому worker'у что делать)
  • Несложно мониторить выполнение заданий
  • Выполнять подзадания
  • Присылать отчеты об exception'ах на email
  • Проверять выполнилось ли задание(удобно для построения Ajax приложений, где юзер ждет факта завершения)

Для использования нужно

 >>> from celery import Celery
>>> celery = Celery()
>>> celery

 В последней строке показано имя класса Celery, имя текущего основного модуля (__main__) и адреса памяти объекта (0x100469fd0).

Всякий раз при добавлении задания, задание добавляется в локальный реестр.

Варианты использования:

  • если задача оформлена как модуль, то запускается как программа,
  •  

Автор: D1VER
Дата публикации: 2013-08-29T01:18:00.000-07:00

Celery для веб-сервисов. Асинхронное распределенное выполнение задач

Докладчик: Роман Иманкулов, NetAngels
Инфраструктура HTTP не предполагает долгих раздумий веб-сервера. Когда необходимо выполнить тяжелую работу без ухудшенияuser experience и снижения надежности системы, возникает потребность в организации очередей команд. В докладе мы рассмотрим вариантыорганизации таких очередей подручными средствами, выясним, чем так хорош Celery, как его можно подключить к вашему проекту, и о чем нужнопомнить программистам и администраторам при его использовании. В заключении рассмотрим возможность выполнения произвольнойпоследовательности команд в бекграунде с использованием celery-tasktree.

Автор: D1VER
Дата публикации: 2013-08-26T02:37:00.002-07:00

Опыт просветления: bash и Python

Не один год работая с Python и bash я, главным образом, использовал

  • первый — для написания программ,
  • второй — для выполнения команд ОС.

При этом моя работа в интерактивном режиме Python сводилась к маленьким исследованиям того, как работает некий фрагмент кода. А в командной строке bash я не пользовался конструкциями, присущими языкам программирования, такими, как if или for, ограничиваясь запуском отдельных команд. Читать