Python高级编程-14设计模式

单例模式

singleton.py

class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance


class MyClass(Singleton):
    a = 1

one = MyClass()
two = MyClass()
two.a = 3
print one.a  # 3


# Although the problem with this pattern is subclassing;
# all instances will be instances of MyClass no matter what the method resolution order (__mro__) says:
class MyOtherClass(MyClass):
    b = 2

three = MyOtherClass()
print three.b  # AttributeError: 'MyClass' object has no attribute 'b'

上述方法的限制是不可再继承得到新的子类,为了避免这种现在,提出一种基于共享状态的替代实现,即Brog。brog.py

class Borg(object):
    _state = {}

    def __new__(cls, *args, **kw):
        ob = super(Borg, cls).__new__(cls, *args, **kw)
        ob.__dict__ = cls._state
        return ob


class MyClass(Borg):
    a = 1

one = MyClass()
two = MyClass()
two.a = 3
print one.a  # 3


class MyOtherClass(MyClass):
    b = 2

three = MyOtherClass()
print three.b  # 2
print three.a  # 3
three.a = 2
print one.a  # 2

不推荐单例的类有多级的继承。Python模块也是一个单例,可以考虑使用带有函数的模块来代替。

外观模式

一般不需要类来提供外观模式,__init__.py模块中的简单函数就足够了。

观察者

observer.py

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')
# a given file was written
# Yeah WriteEvent told me !

访问者

visitor.py

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 content :'
        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())
# list content :
# [1, 2, 5]

a_dict = Vdict({'one': 1, 'two': 2, 'three': 3})
a_dict.accept(Printer())
# dict keys: one,three,two


# Since Python allows code introspection,
# a better idea is to automatically link visitors and visited class:
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())
# list content :
# [1, 2, 5]

visit({'one': 1, 'two': 2, 'three': 3}, Printer())
# dict keys: one,three,two

模板

indexer.py

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[word] = 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)

indexer = BasicIndexer()
print indexer.process('My Tailor is rich and he is also my friend')
# {'friend': 1, 'tailor': 1, 'my': 2, 'als': 1, 'rich': 1}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值