1. 开放封闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应该在不修改原代码的情况下进行修改。

2. 里氏替换原则

所有引用父类的地方必须能透明地使用其子类地方必须能透明地使用其子类的对象,一个简单的例子加强理解

class User(object):
    def print_name(self):
        pass

class VipUser(User):
    def print_name(self):
        """
        保证参数和返回值类型需要和父类一样
        :return:
        """
        pass
def print_name(u):
    """
    不论使用User还是继承User的VipUser,调用的方式是一样的。这就要求User和VipUser的方法参数和返回值类型是一样的
    :param u:
    :return:
    """
    u.print_name()
3. 依赖倒置原则

高层模块不应该依赖底层模块,二者都应该依赖抽象。抽象不应该依赖细节,细节应该应该依赖抽象。要针对接口编程,而不是针对实现变成。通过例子加强理解:

from abc import ABCMeta, abstractmethod

# 接口,抽象不应该依赖细节
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass
        
# 底层代码和高层代码都是细节,细节应该依赖抽象
# 底层代码
class Alipay(Payment):
    def pay(self, money):
        print("支付宝支付了{0}元!".format(money))

class WechatPay(Payment):
    def pay(self, money):
        print("微信支付了%d元!" % (money))

# 高层代码,高层模块不应该依赖底层模块,二者都应该依赖抽象
a = Alipay()
w = WechatPay()
a.pay(100)
w.pay(100)
4. 接口隔离原则

使用多个专门的接口,而不使用单一的总结口,高层的代码不应该依赖那些它不需要的接口。通过例子加强理解:

from abc import ABCMeta, abstractmethod

class LandAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):
        pass

class WaterAnimal(metaclass=ABCMeta):
    @abstractmethod
    def swim(self):
        pass

class SkyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):
        pass

# 高层的代码不应该依赖那些它不需要的接口
class Tiger(LandAnimal):
    def walk(self):
        pass

# 高层的代码不应该依赖那些它不需要的接口
class Frog(LandAnimal, WaterAnimal):
    def walk(self):
        pass
5. 单一职责原则

不要存在多于一个导致类变更的原因,一个类只负责一项职责,一个类只做一件事。把面向过程的代码放到类中,虽然用到了类,但不是面向对象