0

我有这样的代码:

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 等。而且它似乎过于复杂。您对如何改进此代码有任何想法吗?谢谢!

4

2 回答 2

4

据我所知,您只是对减少重复代码感兴趣,这是一个与您的顶级代码等效的选项:

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 make_do(a, b):
    def do(self):
        Base.do(self)
        self._member3 = a
        self._member4 = b
    return do

def make_derived(name, a, b):
    return 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)

这是一个装饰器版本,因为它在评论中被要求:

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

另一个装饰器版本,它覆盖子类do而不是创建新类型(它还允许您使用旧式类):

class Base:
    def do( self ):
        self._member1 = 0
        self._member2 = 1

def add_do(a, b):
    def deco(cls):
        original_do = cls.do
        def do(self):
            original_do(self)
            self._member3 = a
            self._member4 = b
        cls.do = do
        return cls
    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
于 2012-10-04T22:21:42.423 回答
0

如果您只是将类用作数据容器,并使用对数据进行操作的方法,那么使用不同的模式可能会更好:

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)
于 2012-10-04T22:31:10.877 回答