python继承方案_python中迷信继承

Python中的mixin混入

最近在用tornado做项目时,发现一个python老手的源码各种多重

继承,请教那位老手为什么这么做,回答说为了方便。确实使用了多重继承在一些场合确实能够很轻松的解决问题,广泛的定义这种多重继承称为mixin混入,

其实严格意义上mixin混入是动态修改类的多重继承的基类。

简单虚拟一个场景来说明多重继承和mixin的运用场景。

比如一个角色权限系统,我们设定所有管理员都具有登录权限,当然可能这个例子有更好的实现方案,姑且用这个例子说明mixin的实现:

class Admin(object):

def getName(self):

print('admin')

class LoginAuth(Admin):

def getLogin(self):

print('login auth')

admin_a = LoginAuth()

admin_a.getName()

admin_a.getLogin()

1、我们定义Admin类,表示是管理员

2、然后定义LoginAuth类,表示管理员具有登录权限

3、实例化 LoginAuth,就能获取登录的权限 getLogin

那现在如果又加入了3个权限,系统管理员,业务管理员,这时我们又需要分别建立三个不同的基类,来处理一个用户是系统管理员,或者是业务管理员,又或者既是系统管理员又是业务管理员了。

class Admin(object):

def getName(self):

print('admin')

class LoginAuth(Admin):

def getLogin(self):

print('login auth')

class SystemAuth(LoginAuth):

def getSystem(self):

print ('system auth')

class BussinessAuth(LoginAuth):

def getBussiness(self):

print ('bussiness auth')

class SystemAndBussinessAuth(SystemAuth,BussinessAuth):

pass

admin_a = SystemAndBussinessAuth()

admin_a.getName()

admin_a.getLogin()

admin_a.getSystem()

admin_a.getBussiness()

至此,增加了2种权限,我们增加了3个类,如果我们有10种权限,甚至更多那么我们是不是要把所有的排列组合的可能性都列出来,写上N多个派生类呢?

这时候动根据用户的属性,动态的修改继承的基类就会变的很便捷,还是上面的例子,一开始我们不知道访问的管理员具有什么权限。比如:用户访问进来之后,我们才得知,用户是具有 系统管理员、业务管理员权限和会员管理员的人,会员管理员将会根据会员的年龄做出不通的权限设置,代码如下:

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

class Admin(object):

def getName(self):

print('admin')

class LoginAuth():

age = 18

def getLogin(self):

print('login auth')

class SystemAuth():

def getSystem(self):

print ('system auth')

class BussinessAuth():

def getBussiness(self):

print ('bussiness auth')

class MemberAuth():

def getMember(self):

if self.age <18:

print ('child member auth')

else:

print ('adult member auth')

Admin.__bases__ +=  (LoginAuth,SystemAuth,BussinessAuth,MemberAuth,)

admin_a = Admin()

admin_a.getName()

admin_a.getLogin()

admin_a.getSystem()

admin_a.getBussiness()

admin_a.getMember()

运行上述代码之后,将会打印出如下信息:

admin

login auth

system auth

bussiness auth

adult member auth

我们关注这段代码:class MemberAuth():    def getMember(self):        if self.age <18:            print ('child member auth')        else:            print ('adult member auth')

你会发现我们在这个MemberAuth类中根本就没有继承或者定义age属性,但是因为混入技术,可以直接拿其他基类的LoginAuth的age属性来判断,这样的代码在c++中是编译都过不了的。

python的这种灵活性给我们写项目时带来了一些便利,比如老板要对某一些情况,增加一个功能,我们甚至无须修改原有的代码,直接在运行时动态添加一个继承类到基类中,这样直接实例中就可以使用了,而且这个动态添加的继承类还能调用原有其他基类的属性和方法,而无需事先定义它。

但是mixin混入技术也有显著的不足之处:

1、编辑器无法通过联想获取实例的方法,通俗点就是,我们不能通过输入 "." 来让编辑器联想当前实例所具有的属性和方法了,因为这是运行时决定的,所以编辑器无能为力了,只能自己手动写。

2、如果几个不相干的类被mixin混入,那么其他人拿到你的代码,开始看你的混入类定义会比较迷茫,明明没有定义的属性和方法,怎么可以在类中随处调用。

3、动态混入肯定不是没有开销的,它的执行性能必然没有直接多重继承来的好,下面是测试代码:

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

import time

class Admin(object):

def getName(self):

print('admin')

class LoginAuth():

age = 18

def getLogin(self):

print('login auth')

class SystemAuth():

def getSystem(self):

print ('system auth')

class BussinessAuth():

def getBussiness(self):

print ('bussiness auth')

class MemberAuth():

def getMember(self):

if self.age <18:

print ('child member auth')

else:

print ('adult member auth')

class Admin1(Admin,LoginAuth,SystemAuth):

pass

class Admin2(Admin,LoginAuth,BussinessAuth):

pass

class Admin3(Admin,LoginAuth,SystemAuth,BussinessAuth):

pass

class Admin4(Admin,LoginAuth,SystemAuth,MemberAuth):

pass

class Admin5(Admin,LoginAuth,SystemAuth,MemberAuth):

pass

class Admin6(Admin,LoginAuth,SystemAuth,BussinessAuth,MemberAuth):

pass

now1 = float(time.time())

for i in range(100000):

if i % 6 ==0:

admin_a = Admin1()

elif i % 6 ==1:

admin_a = Admin2()

elif i % 6 ==2:

admin_a = Admin3()

elif i % 6 ==3:

admin_a = Admin4()

elif i % 6 ==4:

admin_a = Admin5()

elif i % 6 ==5:

admin_a = Admin6()

now2 =  float(time.time())

print 'instance {0}s'.format(round(now2-now1,4))

now1 = float(time.time())

for i in range(100000):

Admin.__bases__ = (object,)

if i % 6 ==0:

Admin.__bases__ += (LoginAuth,SystemAuth,)

elif i % 6 ==1:

Admin.__bases__ += (LoginAuth,BussinessAuth,)

elif i % 6 ==2:

Admin.__bases__ += (LoginAuth,SystemAuth,BussinessAuth,)

elif i % 6 ==3:

Admin.__bases__ += (LoginAuth,SystemAuth,MemberAuth,)

elif i % 6 ==4:

Admin.__bases__ += (LoginAuth,BussinessAuth,MemberAuth,)

elif i % 6 ==5:

Admin.__bases__ += (LoginAuth,SystemAuth,BussinessAuth,MemberAuth,)

admin_a = Admin()

now2 =  float(time.time())

print 'mixin {0}s'.format(round(now2-now1,4))

最后的执行结果震惊了:

instance 0.049s

mixin 43.457s

mixin混入技术还是慎用的比较好,多重继承已经够用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值