卿哥聊技术

导航

 

今天简单聊聊python的设计模式,GOF设计模式(c++)和Head first design pattern(Java)是两本设计模式的经典,基本可以照搬在python上面,但是你会发现python有很多它特有的东西,比如它并没有多个构造函数,相对应的它有classmethod,所以python设计模式还是有值得聊聊的地方。

构造函数:

python2:

class Person(object):
    def __init__(self, name):
        self.name = name

python3:

class Person:
    def __init__(self, name):
        self.name = name

调用的时候不需要用new,person = Person("xiaozhang")。所有的class都从object继承,python2需要显式而python3都帮你弄好了。继承与object有很多好处,一个好处就是super()。python3 可以直接通过super().parent_method()调用父类的方法而python2需要super(子类名字,self).parent_method()

继承

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    pass

class Cat(Animal):
    pass
>>> animal = Dog("dodo")
>>> animal.name
'dodo'
>>> isinstance(animal, Animal)
True
>>> isinstance(animal, Dog)
True
>>> isinstance(animal, Cat)
False

isinstance 可以用来check object types。

Override

>>> class Animal:
...     sound = ""
...     def speak(self):
...             print("The animal says: " + self.sound)
... 
>>> class Dog(Animal):
...     sound = "WangWang!"
... 
>>> class Cat(Animal):
...     sound = "MiaoMiao"
... 
>>> class Turtle(Animal):
...     pass
... 
>>> Dog().speak()
The animal says: WangWang!
>>> Cat().speak()
The animal says: MiaoMiao
>>> Turtle().speak()
The animal says: 

python不支持方法重载,有些语言比如c++,java可以定义多个同名函数只要参数类型不同即可,python则不可以,后面定义的会覆盖前面定义的方法如果有多个同名方法。

私有类型

python没有访问控制,习惯是用self._something表示这东西是私有的请不要直接获取它,然而你可以随便拿。

你也可以使用__,python会mangle这个变量__something为_classname__something,如果知道这层name mangling你还是可以获取它。

设计模式之read only

python有一个decorator叫做property,加了property的方法,只能读,不能写。如果你想写,要额外加被decorate的方法名.setter。setter里可以做一些input check。有了property我们就可以创造性的refactor一些类。

设计模式之pub-sub

import os
import time

class FileWatcher(object):
    def __init__(self, path_of_file_to_watch):
        self.path = path_of_file_to_watch
        self.observers = set()
    def register(self, name):
        self.observers.add(name)
    def unregister(self, name):
        self.observers.discard(name)
    def notify(self, message):
        for i in self.observers:
            i.update(message)

class FileObserver(object):
    def __init__(self, name):
        self.name = name
    def update(self, message):
        print "%s noticed that the file is now %d bytes" % (self.name, message)

filename = "/tmp/test.txt"
f = FileWatcher(filename)
bob = FileObserver("bob")
john = FileObserver("john")
stacy = FileObserver("stacy")
f.register(bob)
f.register(john)
f.register(stacy)

init_size = os.stat(filename).st_size
while True:
    if os.stat(filename).st_size != init_size:
        f.notify(os.stat(filename).st_size)
        init_size = os.stat(filename).st_size
    time.sleep(1)

classmethod模式

def __init__(self, something):
    ***

@classmethod
def some_alternative_constructor(cls, some_other_thing):
    ***
    something = some_other_thing balbla
    return cls(something)

调用的时候直接用类名.另一个构造函数,返回需要的对象。直接适用于子类。

staticmethod

相当于定义函数,不用加self 啦,cls啦,相当于直接写function,然后可以用类名直接调用。

posted on 2018-04-23 11:27  卿哥聊技术  阅读(397)  评论(0编辑  收藏  举报