行为型模式用于简化类之间的交互。这里提供了三个例子:观察者(observer)、访问者(visitor)、模板(template)
1. 观察者
# _*_ coding=utf-8 _*_
class Event(object):
_observers = []
def __init__(self, subject):
self.subject = subject
@classmethod
def register(cls, observer):
if observer not in cls._observers:
cls._observers.append(observer)
@classmethod
def unregister(cls, observer):
if observer in cls._observers:
cls._observers.remove(observer)
@classmethod
def notify(cls, subject):
event = cls(subject)
for observer in cls._observers:
observer(event)
class WriteEvent(Event):
def __repr__(self):
return 'WriteEvent'
def log(event):
print '%s was written' % event.subject
WriteEvent.register(log)
class AnotherObserver(object):
def __call__(self, event):
print 'Yeah %s told me!' % event
WriteEvent.register(AnotherObserver())
WriteEvent.notify("a given file")
2. 访问者
# _*_ coding=utf-8 _*_
class vlist(list):
def accept(self, visitor):
visitor.visit_list(self)
class vdict(dict):
def accept(self, visitor):
visitor.visit_dict(self)
class Printer(object):
def visit_list(self, ob):
print 'list cintent'
print str(ob)
def visit_dict(self, ob):
print 'dict keys: %s' % ','.join(ob.keys())
# a_list = vlist([1, 2, 5])
# a_list.accept(Printer())
# a_dict = vdict({'one': 1, 'two': 2, 'three': 3})
# a_dict.accept(Printer())
# def visit(visited, visitor):
# cls = visited.__class__.__name__
# meth = 'visit_%s' % cls
# method = getattr(visitor, meth, None)
# if method is not None:
# method(visited)
#
# visit([1, 2, 5], Printer())
# visit({'one': 1, 'two': 2, 'three': 3}, Printer())
import os
def visit(directory, visitor):
for root, dirs, files in os.walk(directory):
for file in files:
ext = os.path.splitext(file)[-1][1:]
if hasattr(visitor, ext):
getattr(visitor, ext)(file)
class FileReader(object):
def pdf(self, file):
print 'processing %s' % file
walker = visit("/Users/lucas/Downloads", FileReader())
3. 模板
# _*_ coding=utf-8 _*_
from itertools import groupby
class Indexer(object):
def process(self, text):
text = self._normalize_text(text)
words = self._split_text(text)
words = self._remove_stop_words(words)
stemmed_words = self._stem_words(words)
return self._frequency(stemmed_words)
def _normalize_text(self, text):
return text.lower().strip()
def _split_text(self, text):
return text.split()
def _remove_stop_words(self, words):
raise NotImplementedError
def _stem_words(self, words):
raise NotImplementedError
def _frequency(self, words):
counts = {}
for word in words:
counts[words] = counts.get(word, 0) + 1
return counts
class BasicIndexer(Indexer):
_stop_words = ('he', 'she', 'is', 'and', 'or')
def _remove_stop_words(self, words):
return [word for word in words if word not in self._stop_words]
def _stem_words(self, words):
return [(len(word) > 2 and word.rstrip('aeiouy')
or word) for word in words]
def _frequency(self, words):
freq = {}
for word in words:
freq[word] = freq.get(word, 0) + 1
return freq
indexer = BasicIndexer()
print indexer.process(('My Tailor is rich and he is also my friend'))