python教程

当前位置:首页 > python面向对象 > 当前文章

python面向对象

类的约束子类继承父类与鸭子类型

2021-11-09 179赞 老董笔记

  上篇文章有1个疑问就是父类如何去约束子类呢?简单的方法是直接手动抛出NotImplementedError异常来提示开发者。

  假设某公司有ABC三个程序员,每个人分别操作mysql、clickhouse、redis数据库。为了统一管理,老板规定操作数据库的函数必须用同1个名字my_conncet。这样万一有人离职,别人也好接手对方的代码。

  为了做到这一点,老板事先定义1个类,在这个类里有my_connect方法,每个程序员开发时候继承这个类,连接数据库时必须去使用my_connect方法。如果某个员工忘记了在子类去实现my_connect方法,那么在调用my_connect的时老板希望提醒他在子类里去实现my_connect。

# -*- coding: utf-8 -*-

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

    def my_connect(self):
        raise NotImplementedError("check subclass my_connect method")

class Clickhouse(Database):
	def my_connect(self):
		print(f'{self.name}, connect Clickhouse')

class Redis(Database):
	def my_connect(self):
		print(f'{self.name}, connect Redis!')

class Mysql(Database):
	def lian_jie(self):
		print(f'{self.name}, connect Mysql!')

if __name__ == "__main__":
    data_obj1 = Clickhouse('lao wang')
    data_obj2 = Redis('lao dong')
    data_obj3 = Mysql('lao zhang')
    
    data_obj1.my_connect()
    data_obj2.my_connect()
    data_obj3.my_connect()

ao wang, connect ClickhouseTraceback (most recent call last):

lao dong, connect Redis!
  File "C:UsersAdministratorDesktop	est.py", line 73, in <module>
    data_obj3.my_connect()
  File "C:UsersAdministratorDesktop	est.py", line 51, in my_connect
    raise NotImplementedError("subclass need inherits the parent class")
NotImplementedError: check subclass my_connect method


  上面的例子加工一下可以增加1个获取数据的类来统一接口,如下

# -*- coding: utf-8 -*-

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

    def my_connect(self):
        raise NotImplementedError("subclass need inherits the parent class")

class Clickhouse(Database):
	def my_connect(self):
		print(f'{self.name}, connect Clickhouse')

class Redis(Database):
	def my_connect(self):
		print(f'{self.name}, connect Redis!')

class Mysql(Database):
	def my_connect(self):
		print(f'{self.name}, connect Mysql!')

# 统一接口
class GetData():
    def conncet(self,obj):
        obj.my_connect()

if __name__ == "__main__":
    data_obj1 = Clickhouse('lao wang')
    data_obj2 = Redis('lao dong')
    obj = GetData()
    obj.conncet(data_obj1)
    obj.conncet(data_obj2)

lao wang, connect Clickhouse
lao dong, connect Redis!

  鸭子类型

  上述代码中obj.conncet()函数的参数data_obj不需要声明是哪个类(声明类型),而在一些语言中需要显式的声明好类型obj.conncet(类名 对象)才可以用,这就是多态的体现。不关心对象本身的类型,只要确保传入的对象拥有同样的调用方法就是所谓的鸭子类型,上述Database类型对象可视为鸭子类型。鸭子类型不是1种数据类型,他是1种动态类型语言的设计风格。这个名字很怪异,但是不难理解。鸭子类型可以约束一些开发规范,节省代码量。

感兴趣直接点击图片获取>>

文章评论

类的约束子类继承父类与鸭子类型文章写得不错,值得赞赏