我想用我可以插入类的方法创建轻量级接口.这是
Scala中的一个简短示例:
class DB { def find(id: String) = ... } trait Transformation extends DB { def transform(obj: String): String override def find(id: String) = transform(super.find(id)) } trait Cache extends DB { val cache = Cache() override def find(id: String) = { ... if (cache.contains(id)) cache.find(id) else { cache.set(id,super.find(id)) cache.get(id) } } }
使用这些类(特征),我们可以使用Transformation,使用Cache或两者来实例化DB类.请注意,Transformation有一个抽象方法转换,仍然需要在具体类中实现.
new DB() with Transformation { def transform(obj: String): obj.toLower() } new DB() with Cache new DB() with Transformation with Cache { def transform(obj: String): obj.toLower() }
有没有办法在Python中实现这样的东西?我知道Python有一个Traits包,但它的目的似乎不同.
解决方法
最简单的解决方案可能就是创建另一个子类.
# assuming sensible bases: class DB(object): ... class Transformation(object): def transform(self,obj): ... def get(self,id): return self.transform(super(Transformation,self).get(id)) class Cache(object): def __init__(self,*args,**kwargs): self.cache = Cache() super(Cache,self).__init__(*args,**kwargs) def get(self,id): if id in self.cache: return self.cache.get(id) else: self.cache.set(id,super(Cache,self).get(id)) return self.cache.get(id) class DBwithTransformation(Transformation,DB): # empty body pass
如果你固执地拒绝实际给这个班级命名,你可以直接打电话给你.更换
class DBwithTransformation(Transformation,DB): pass db = DBwithTransformation(arg1,arg2,...)
同
db = type("DB",(Transformation,DB),{})(arg1,...)
这并不比Scala示例差太多.
由于python类型系统的微妙之处,不从主类(DB)继承的mixin首先出现在基本列表中.不这样做会阻止mixin类正确地覆盖主基类的方法.
同样的微妙之处可以让你有额外的功能是适当的派生类.钻石继承模式不是问题;基类只出现一次,无论有多少中间基类从它们继承(毕竟,它们都最终从对象继承).