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

重複したコードを減らすことに関心があると私が言える限り、これがあなたの一番上のコードに相当する1つのオプションです。

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 に答える