Здесь есть две вещи:
re.findall
возвращает захваченные тексты, если шаблон регулярного выражения содержит в нем группы захвата r'\\.'
в вашем шаблон соответствует двум последовательным символам, \
и любому символу, отличному от новой строки. См. ссылку findall
:
Если одна или несколько групп присутствуют в шаблоне, верните список групп; это будет список кортежей, если шаблон имеет более одной группы. Пустые совпадения включаются в результат, если они не касаются начала другого совпадения.
blockquote>Обратите внимание, что чтобы
re.findall
возвращали только совпадающие значения, вы обычно можете
- удаляет избыточные группы захвата (например,
(a(b)c)
->abc
)- преобразует все группы захвата в , не захватывая (то есть замените
(
на(?:
) , если отсутствуют обратные ссылки, которые относятся к значениям группы в шаблоне (см. ниже)- вместо
re.finditer
использовать[x.group() for x in re.finditer(pattern, s)]
)В вашем случае
findall
вернул все захваченные тексты, которые были пустыми, потому что вы\\
в [литерале] строкиr''
, которые пытались сопоставить литерал\
.Чтобы соответствовать номерам, вам нужно использовать
-?\d*\.?\d+
Регулярное выражение соответствует:
-?
- Дополнительный знак минус\d*
- Необязательные цифры\.?
- Дополнительный десятичный разделитель\d+
- 1 или более цифр.См. demo
Вот демон IDEONE :
import re s = r'abc123d, hello 3.1415926, this is my book' pattern = r'-?\d*\.?\d+' L = re.findall(pattern, s) print(L)
Лично я не вижу различия между обратными вызовами, слушателями и делегатами.
шаблон "наблюдатель" (иначе слушатели, иначе "несколько обратных вызовов") легко реализовать - просто содержат список наблюдателей, и добавляют или удаляют callables из него. Эти callables могут быть функциями, связанными методами или классами с __call__
волшебный метод. Все, что необходимо сделать, определяют интерфейс, который Вы ожидаете от них - например, делаете они получают любые параметры.
class Foo(object):
def __init__(self):
self._bar_observers = []
def add_bar_observer(self, observer):
self._bar_observers.append(observer)
def notify_bar(self, param):
for observer in self._bar_observers:
observer(param)
def observer(param):
print "observer(%s)" % param
class Baz(object):
def observer(self, param):
print "Baz.observer(%s)" % param
class CallableClass(object):
def __call__(self, param):
print "CallableClass.__call__(%s)" % param
baz = Baz()
foo = Foo()
foo.add_bar_observer(observer) # function
foo.add_bar_observer(baz.observer) # bound method
foo.add_bar_observer(CallableClass()) # callable instance
foo.notify_bar(3)
Я не могу говорить за общие подходы, но эта страница (фактическая копия недоступна), имеет реализацию шаблона "наблюдатель", который я люблю.
Вот интернет-ссылка Архива: http://web.archive.org/web/20060612061259/http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html
Все это зависит на уровне сложности, которой требует Ваше приложение. Для простых событий обратные вызовы, вероятно, сделают. Для более сложных шаблонов и разъединенных уровней необходимо использовать некоторый публиковать - подписывают реализацию, такой как PyDispatcher или pubsub wxPython.
См. также это обсуждение .
Большинство библиотек Python, которыми я пользовался, реализует модель обратного вызова для своих уведомлений о событии, которые я думаю, удовлетворяет языку довольно хорошо. Pygtk делает это путем получения всех объектов от GObject, который реализует основанную на обратном вызове обработку сигнала. (Хотя это - функция базового C GTK реализация, не что-то вдохновленное языком.) Однако Pygtkmvc делает интересное задание реализации шаблона "наблюдатель" (и MVC) поверх Pygtk. Это использует очень декоративную основанную на метаклассе реализацию, но я нашел, что это работает довольно хорошо на большинство случаев. Код довольно прост для следования, также, если Вы интересуетесь наблюдением одного пути, которым это было сделано.
Лично, я только видел используемые обратные вызовы. Однако я не видел, что так много управляемого событиями Python кодирует так YMMV.
Я видел слушателей и используемые обратные вызовы. Но AFAIK там не является никакой Python путь. Они должны быть одинаково выполнимыми, если рассматриваемое приложение подходит.
matplotlib.cbook
модуль содержит класс CallbackRegistry
, на который Вы могли бы хотеть взглянуть. От документация :
Handle registering and disconnecting for a set of signals and callbacks: signals = 'eat', 'drink', 'be merry' def oneat(x): print 'eat', x def ondrink(x): print 'drink', x callbacks = CallbackRegistry(signals) ideat = callbacks.connect('eat', oneat) iddrink = callbacks.connect('drink', ondrink) #tmp = callbacks.connect('drunk', ondrink) # this will raise a ValueError callbacks.process('drink', 123) # will call oneat callbacks.process('eat', 456) # will call ondrink callbacks.process('be merry', 456) # nothing will be called callbacks.disconnect(ideat) # disconnect oneat callbacks.process('eat', 456) # nothing will be called
Вы, вероятно, не хотите зависимости к matplotlib пакету. Я предлагаю Вас просто вставка копии класс в Ваш собственный модуль от исходный код .
Я ищу реализацию для регистрации и обработки событий в Python. Мой единственный опыт связан с Gobject , но я использовал его только с PyGtk. Он гибкий, но может быть слишком сложным для некоторых пользователей. Я также наткнулся на несколько других интересных кандидатов, но неясно, как именно они сравниваются друг с другом.