Refactoring similar subclasses

Discussion in 'Python' started by Steven D'Aprano, Sep 11, 2010.

  1. I have some code that currently takes four different classes, A, B, C and
    D, and subclasses each of them in the same way:

    class MyA(A):
    def method(self, x):
    result = super(MyA, self).method(x)
    if result == "spam":
    return "spam spam spam"
    return result
    # many more methods overloaded


    class MyB(B):
    def method(self, x):
    result = super(MyB, self).method(x)
    if result == "spam":
    return "spam spam spam"
    return result
    # many more methods overloaded


    and so on, for MyC and MyD. There's a lot of duplicated code in there.
    What techniques do you suggest for reducing the code duplication? I
    thought about some variation of:

    names = "MyA MyB MyC MyD".split()
    bases = [A, B, C, D]
    d = dict-of-overloaded-methods
    for name, base in zip(names, bases):
    globals()[name] = type(name, [base], d)


    but I'm not sure that this is a good approach, or how to inject the right
    arguments to super in the dict.

    Any suggestions or guidelines?


    --
    Steven
    Steven D'Aprano, Sep 11, 2010
    #1
    1. Advertising

  2. Steven D'Aprano

    Peter Otten Guest

    Steven D'Aprano wrote:

    > I have some code that currently takes four different classes, A, B, C and
    > D, and subclasses each of them in the same way:
    >
    > class MyA(A):
    > def method(self, x):
    > result = super(MyA, self).method(x)
    > if result == "spam":
    > return "spam spam spam"
    > return result
    > # many more methods overloaded
    >
    >
    > class MyB(B):
    > def method(self, x):
    > result = super(MyB, self).method(x)
    > if result == "spam":
    > return "spam spam spam"
    > return result
    > # many more methods overloaded
    >
    >
    > and so on, for MyC and MyD. There's a lot of duplicated code in there.
    > What techniques do you suggest for reducing the code duplication? I
    > thought about some variation of:
    >
    > names = "MyA MyB MyC MyD".split()
    > bases = [A, B, C, D]
    > d = dict-of-overloaded-methods
    > for name, base in zip(names, bases):
    > globals()[name] = type(name, [base], d)
    >
    >
    > but I'm not sure that this is a good approach, or how to inject the right
    > arguments to super in the dict.
    >
    > Any suggestions or guidelines?


    You could use a mixin:

    class Mixin(object):
    def method(self, x):
    result = super(Mixin, self).method(x)
    if result == "spam":
    return "spam spam spam"
    return result

    # ...

    for name, base in zip(names, bases):
    globals()[name] = type(name, (Mixin, base), {})

    Peter
    Peter Otten, Sep 11, 2010
    #2
    1. Advertising

  3. On Sat, 11 Sep 2010 08:53:38 +0200, Peter Otten wrote:

    > Steven D'Aprano wrote:
    >
    >> I have some code that currently takes four different classes, A, B, C
    >> and D, and subclasses each of them in the same way:

    [...]
    >> Any suggestions or guidelines?

    >
    > You could use a mixin:


    Nice! I'll give it a try. I knew that sooner or later I'd find a reason
    for mixins :)


    --
    Steven
    Steven D'Aprano, Sep 11, 2010
    #3
  4. Steven D'Aprano a écrit :
    > I have some code that currently takes four different classes, A, B, C and
    > D, and subclasses each of them in the same way:
    >
    > class MyA(A):
    > def method(self, x):
    > result = super(MyA, self).method(x)
    > if result == "spam":
    > return "spam spam spam"
    > return result
    > # many more methods overloaded
    >
    >
    > class MyB(B):
    > def method(self, x):
    > result = super(MyB, self).method(x)
    > if result == "spam":
    > return "spam spam spam"
    > return result
    > # many more methods overloaded
    >


    If that's really what your code is doing - I mean, calling the super()
    implementation, checking the result and eventually returning something
    else instead - then a simple decorator might be enough... Could even be
    "applied" by the metaclass.
    Bruno Desthuilliers, Sep 13, 2010
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bura Tino

    Subclasses in interfaces

    Bura Tino, Nov 3, 2003, in forum: Java
    Replies:
    17
    Views:
    556
    Thomas G. Marshall
    Nov 7, 2003
  2. Praveen
    Replies:
    1
    Views:
    368
    Woebegone
    Nov 21, 2003
  3. Marc Twain
    Replies:
    2
    Views:
    663
    Chris Uppal
    Jan 7, 2004
  4. Steve Nakhla
    Replies:
    0
    Views:
    614
    Steve Nakhla
    Sep 27, 2004
  5. hitectahir
    Replies:
    1
    Views:
    327
    Esmond Pitt
    Oct 19, 2004
Loading...

Share This Page