为什么Python不用设计模式

前言

虽然没有学习过Java,但是Java里那一直挂在嘴边的设计模式听到的次数就太多了,听的多了不代表就懂了。

所谓设计模式,主要是三个原则:

  • 面向接口编程,而不是面向实现编程
  • 优先使用组合,而不是继承

Python时间也不短了,但一直都是用成熟的库,很少自己去封装一套,最多也就是改写一些方法,几乎没听见过Python大佬提过设计模式的事。

那么Python的设计模式是啥样的呢?

Python的接口

区别于JAVA的接口(interface),Python没有所谓的接口,但动态语言有一种语法称为Duck Typing,可以实现接口的功能。

class Pig():
    def eat(self):
        print("pig eat all!")

class Cat():
    def eat(self):
        print("cat eat!")


def eat(entity):
    entity.eat() 


pig = Pig()
cat = Cat()

eat(pig)
eat(cat)

这串代码中PigCat两个类都没去做特意的接口,但是可以通过同一个方式调用eat这个方法,简单明了的实现。

适配器模式(Adapter)

假设目前有个需求是把日志记录到文件,现在有如下完成方法:

def log(f, msg):
    f.write(mag)

某天,需求变更,需要将日志记录到数据库,但是数据库根本没有write方法,那么就尝试添加数据库write方法:

class DBAdapter():
    def __inti__(self, db):
        self.db = db

    def writer(self, msg):
        self.db.insert(msg)

具体的实现如下:

db_adapter = DBAdapter(db)
log(db_adater, "ABCDEFG")

通过简单的添加write的方法即可简单实现变更后的需求。

代理模式(Proxy Pattern)

假设目前需求要求实现一个访问器:

class Visitor():
    def __init__(self, ip):
        self.connect = connect((localhost, 9999), ip)

    def see(self):
        self.connect.getinfo()


visitor = Visitor()

现在变更需求,要求只能本地主机访问这个服务:

class ProxyVistor():
    def __init__(self, ip):
        self.connect = Vistor(localhost)

    def see():
        self.connecet.see()

visitor = ProxyVistor(ip)
visitor.see()

代理模式不是太懂,这部分的实现应该就是这样吧。哈哈哈哈~~

单例模式(Singleton Pattern)

尝试新建一个文件,命名single.py

class Single():
    def __init__(self):
        print("AAA")


instance = Single()

del Single()  # 这个操作是真的骚,删除构造函数!!!

使用single:

import single

single.instance

instance = Singele()  # 运行这步会报错

这步操作是真的骚!我特么完全没想到还有这操作!!!!!!!!!!!!!!!

访问者模式(Visitor)

参考:

class TreeNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
    def accept(self, visitor):
        if self.left is not None:
            self.left.accept(visitor)

        visitor.visit(self)

        if self.right is not None:
            self.right.accept(visitor)

class PrintVisitor:
    def visit(self,node):
        print(node.data)

root = TreeNode('1')
root.left = TreeNode('2')
root.right = TreeNode('3')

visitor = PrintVisitor()

root.accept(visitor)   #输出2, 1, 3

逻辑这么复杂纯粹是反人类…

采用generator改写:

class TreeNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

    def __iter__(self):
        return self.__generator()

    def __generator(self):
        if self.left is not None:
            yield from iter(self.left) 
        yield from self.data

        if self.right is not None:
            yield from iter(self.right) 

root = TreeNode('1')
root.left = TreeNode('2')
root.right = TreeNode('3')

for ele in root:
    print(ele)

文章参考:


 上一篇
scrapy学习 scrapy学习
配置文件文件以ini的方式记录,从以下路径寻找scrapy.cfg文件: /etc/srcapy.cfg或c:\scrapy\scrapy.cfg(系统层面) ~/.config/scrapy.cfg($XDG_CONFIG_HOME)及
2019-03-21
下一篇 
性能测试----坑 性能测试----坑
服务器无法连接到执行机的性能监控 问题 服务器端开启ServerAgent,执行机无法连通 解决方案 问题的原因是由于服务器主机默认4444端口被占用,可以采用换端口的方式连通。 端口可以自定义 ./startAgent.sh -
2019-03-15
  目录