Python:简化继承器方法
我有这样的代码:Python:简化继承器方法,python,class,inheritance,subclass,factory,Python,Class,Inheritance,Subclass,Factory,我有这样的代码: class Base: def do( self ): self._member1 = 0 self._member2 = 1 class Derived1(Base): def do(self): Base.do(self) self._member3 = 0 self._member4 = 1 class Derived2(Base): def do(self): Base.do(self) self.
class Base:
def do( self ):
self._member1 = 0
self._member2 = 1
class Derived1(Base):
def do(self):
Base.do(self)
self._member3 = 0
self._member4 = 1
class Derived2(Base):
def do(self):
Base.do(self)
self._member3 = 2
self._member4 = 3
class Derived3(Base):
def do(self):
Base.do(self)
self._member3 = 9
self._member4 = 3
等等。以下是我所做的:
class Base(object):
'''Base class.'''
def do(self):
self._member1 = 0
self._member2 = 1
class Derived1(Base): pass
class Derived2(Base): pass
class Derived3(Base): pass
class Derived4(Base): pass
class DerivedFactory(object):
'''Factory to create derived classes.'''
members = \
{
1: (Derived1, 0, 1),
2: (Derived2, 4, 5),
3: (Derived3, 6, 7),
4: (Derived4, 8, 9),
}
def do(self, key=1):
derived = self.members[key][0]()
derived.do() # Perform method from Base
derived._member3 = self.members[key][1]
derived._member4 = self.members[key][2]
print(derived)
print('\t%s' % derived.__dict__)
if __name__ == '__main__':
factory = DerivedFactory()
for key in range(1, 5):
derived = factory.do(key)
然而,它并不像你看到的那样完美。我需要声明Derived1、Derived2等等。它似乎过于复杂了。你对如何导入这段代码有什么想法吗?谢谢 据我所知,您只是对减少重复代码感兴趣,这里有一个选项相当于您的顶级代码:
class Base:
def do( self ):
self._member1 = 0
self._member2 = 1
def make_do(a, b):
def do(self):
Base.do(self)
self._member3 = a
self._member4 = b
return do
class Derived1(Base):
do = make_do(0, 1)
class Derived2(Base):
do = make_do(2, 3)
class Derived3(Base):
do = make_do(9, 3)
Oren在评论中建议的较短版本(请注意,要使其起作用,Base
需要是一个新样式的类):
这是一个装饰版本,因为它是在评论中要求的:
class Base(object):
def do( self ):
self._member1 = 0
self._member2 = 1
def add_do(a, b):
def do(self):
Base.do(self)
self._member3 = a
self._member4 = b
def deco(cls):
return type(cls.__name__, (Base,), {'do': do})
return deco
@add_do(0, 1)
class Derived1(Base): pass
@add_do(2, 3)
class Derived2(Base): pass
@add_do(9, 3)
class Derived3(Base): pass
另一个decorator版本,它重写子类“do
,而不是创建新类型(它还允许您使用旧样式的类):
据我所知,您只是对减少重复代码感兴趣,这里有一个选项相当于您的顶级代码:
class Base:
def do( self ):
self._member1 = 0
self._member2 = 1
def make_do(a, b):
def do(self):
Base.do(self)
self._member3 = a
self._member4 = b
return do
class Derived1(Base):
do = make_do(0, 1)
class Derived2(Base):
do = make_do(2, 3)
class Derived3(Base):
do = make_do(9, 3)
Oren在评论中建议的较短版本(请注意,要使其起作用,Base
需要是一个新样式的类):
这是一个装饰版本,因为它是在评论中要求的:
class Base(object):
def do( self ):
self._member1 = 0
self._member2 = 1
def add_do(a, b):
def do(self):
Base.do(self)
self._member3 = a
self._member4 = b
def deco(cls):
return type(cls.__name__, (Base,), {'do': do})
return deco
@add_do(0, 1)
class Derived1(Base): pass
@add_do(2, 3)
class Derived2(Base): pass
@add_do(9, 3)
class Derived3(Base): pass
另一个decorator版本,它重写子类“do
,而不是创建新类型(它还允许您使用旧样式的类):
如果您只是使用类作为数据容器,并使用对数据进行操作的方法,则最好使用不同的模式:
from collections import namedtuple
Base = namedtuple("Base", ["member1", "member2"])
Derived = namedtuple("Derived", Base._fields + ("member3", "member4"))
def do(base_or_derived):
print "Member1:", base_or_derived.member1
print "Member2:", base_or_derived.member2
if not isinstance(base_or_derived, Base):
print "Member3:", base_or_derived.member3
print "Member4:", base_or_derived.member4
if __name__ == "__main__":
base = Base(0, 1)
derived1 = Derived(0, 1, 0, 1)
derived2 = Derived(0, 1, 2, 3)
derived3 = Derived(0, 1, 9, 3)
for item in [base, derived1, derived2, derived3]:
do(item)
如果您只是使用类作为数据容器,并使用对数据进行操作的方法,则最好使用不同的模式:
from collections import namedtuple
Base = namedtuple("Base", ["member1", "member2"])
Derived = namedtuple("Derived", Base._fields + ("member3", "member4"))
def do(base_or_derived):
print "Member1:", base_or_derived.member1
print "Member2:", base_or_derived.member2
if not isinstance(base_or_derived, Base):
print "Member3:", base_or_derived.member3
print "Member4:", base_or_derived.member4
if __name__ == "__main__":
base = Base(0, 1)
derived1 = Derived(0, 1, 0, 1)
derived2 = Derived(0, 1, 2, 3)
derived3 = Derived(0, 1, 9, 3)
for item in [base, derived1, derived2, derived3]:
do(item)
您还可以使用
type
函数动态创建类:def make_-derived(name,a,b):type(name,(Base,),{'do':make_-do(a,b)})Derived1=make_-derived('Derived1',0,1)Derived2=make_-derived('Derived2',2,3)Derived3=make_-derived('Derived3',9,3)好的建议,添加到我的答案中。@Oren确实,它被称为:)在我的答案中添加了一个带有装饰器的版本(不使用元类)。在最后一种情况下,值得一提的是,类装饰器将忽略原始类下的任何其他定义(如果编写了任何其他内容而不是过程
)您还可以使用type
函数动态创建类:def make_-derived(name,a,b):type(name,(Base,),{'do':make_-do(a,b)})Derived1=make_-derived('Derived1',0,1)Derived2=make_-derived('Derived2',2,3)Derived3=make_-derived('Derived3',9,3)好的建议,添加到我的答案中。@Oren确实,它的名称是:)在我的答案中添加了一个带有修饰符的版本(不使用元类)。在最后一个例子中,值得一提的是,类修饰符将忽略原始类下的任何其他定义(如果编写了任何其他定义而不是pass
)否,成员只能在do
方法中初始化。否,只能在do
方法中初始化成员。