zoukankan      html  css  js  c++  java
  • python设计模式浅析

    今天简单聊聊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,然后可以用类名直接调用。

  • 相关阅读:
    笔记 : windows系统下 命令行 php --version 的版本与phpinfo()版本不一致问题
    笔记 : WampServe加装PHP版本(7.2.3)为例
    Browsersync结合gulp和nodemon实现express全栈自动刷新
    PHP与JSP简单比较
    BDD 与DSL 入门
    1.display:flex布局笔记
    Css预处理器---Less(三)
    python_30期_第2讲【字符串&运算符】
    python_30期_第5讲【while循环+for循环】
    class_05py作业
  • 原文地址:https://www.cnblogs.com/huashao1985/p/8916730.html
Copyright © 2011-2022 走看看