Python设计模式访问者模式
今日分享主题:Python设计模式之访问者模式。
定义
访问者模式是指封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义于作用于这些元素的新操作。
应用场景
1、要遍历不同的对象,根据对象进行不同的操作的场景;
2、当一个对象被多个不同对象顺次处理的情况,可以考虑使用访问者模式;
3、报表生成器也可以使用访问者模式实现,报表的数据源由多个不同的对象提供,每个对象都是Visitor,报表这个Element顺次Accept各访问者完善并生成对象。
Python代码实现1classPerson(object):2pass34classMan(Person):5pass67classWoman(Person):8pass910classGirl(Woman,Man):11pass1213classSon(Man,Woman):14pass1516classVisitor(object):17defvisit(self,person,args,kwargs):18methNone19为了方便且快速地看清继承关系和顺序,可以用mro方法来获取这个类的调用顺序。20forclsinperson。class。mro:21print(cls)22methnamevisitcls。name23print(,methname)24print(self)2526这里讲解一下:Python的hasattr(),getattr(),setattr()函数使用方法27一:hasattr(object,name)28判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True,否则返回False。29二:getattr(object,name〔,default〕)30获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。31三:setattr(object,name,values)32给对象的属性赋值,若属性不存在,先创建再赋值。3334methgetattr(self,methname,None)35ifmeth:36break3738ifnotmeth:39methself。genericvisit40returnmeth(person,args,kwargs)4142普通访问入口43defgenericvisit(self,person,args,kwargs):44这里可以写处理逻辑45print(genericvisitperson。class。name)4647妇女访问入口48defvisitWoman(self,person,args,kwargs):49这里可以写处理逻辑50print(visitWomanperson。class。name)5152男人访问入口53defvisitMan(self,person,args,kwargs):54这里可以写处理逻辑55print(visitManperson。class。name)5657ifnamemain:58pPerson()59manMan()60womanWoman()61girlGirl()62sonSon()6364visitorVisitor()65visitor。visit(p)66visitor。visit(man)67visitor。visit(son)68visitor。visit(woman)69visitor。visit(girl)
输出结果如下:1genericvisitPerson2visitManMan3visitManSon4visitWomanWoman5visitWomanGirl
备注
classMan(Person)这里会在类的继承关系中会指定调用visitMan方法
classSon(Man,Woman)这里会在类的继承关系中优先找到并调用visitMan方法
classWoman(Person)这里会在类的继承关系中会指定调用visitWoman方法
classGirl(Woman,Man)这里会在类的继承关系中优先找到并调用visitWoman方法
找到了对应的方法就可以执行对应的业务逻辑。
优点:
1、将不同的职责非常明确地分离开来,符合单一职责原则;
2、职责的分开也直接导致扩展非常优良,灵活性非常高,加减元素和访问者都非常容易。