class factory example needed (long)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gary Ruben

    #1

    class factory example needed (long)

    I have a class factory problem. You could say that my main problem is
    that I don't understand class factories.
    My specific problem:
    I have a class with several methods I've defined.
    To this class I want to add a number of other class methods where the
    method names are taken from a list.
    For each list member, I want to build a method having the list member
    name so that I can override another method of the same name for objects
    which are instances of this class. Finally, I want my class factory
    which creates the method to call the overridden method.

    I'm sure my description is confusing, so I'll try to illustrate it.


    import Numeric
    # The Numeric module contains a whole lot of methods which operate on
    certain number types

    class foo:
    """ this is a number type class
    """
    def __init__(self, value):
    self.value = float(value)
    def __str__(self):
  • Gary Ruben

    #2
    Re: class factory example needed (long)

    Thanks for the very helpful reply Rainer,
    I thought I couldn't use setattr because I need the syntactic sugar
    sqrt(f) to work, but with your example code Numeric.sqrt(f) does in fact
    work correctly. I also need to do a bit more than may be possible with a
    simple lambda function, but I should be able to sort it out from here
    with the info you provided,
    thanks again,
    Gary

    Rainer Mansfeld wrote:
    <snip>[color=blue]
    > Hi Gary,
    >
    > you want your 'class factory' to change the methods of Numeric, so that
    > they accept foo objects and return foo objects?
    > I've not the slightest idea how to achieve that.
    >
    > If OTOH you want your foo class to have sqrt, arccos, etc. methods
    > without defining them explicitly, I think you're looking for something
    > like:
    >
    > . import Numeric
    > .
    > . class Foo(object):
    > . def __init__(self, value):
    > . self.value = float(value)
    > . for u in ['sqrt', 'cos', 'tan']:
    > . setattr(self, u, lambda uf=getattr(Nume ric, u):
    > . uf(self.value + 42.0))
    >[color=green][color=darkred]
    > >>> f = Foo(7)
    > >>> f.sqrt()[/color][/color]
    > 7.0
    >
    > HTH
    > Rainer
    >[/color]

    Comment

    • Gary Ruben

      #3
      Re: class factory example needed (long)

      OK, I've managed to get this to work with Rainer's method, but I
      realised it is not the best way to do it, since the methods are being
      added by the constructor, i.e. they are instance methods. This means
      that every time a foo object is created, a whole lot of code is being
      run. It would be better to do the same thing with class 'static'
      methods, if this is possible, so that the methods are created just once.
      Is this possible?
      Gary

      Rainer Mansfeld wrote:
      <snip>[color=blue]
      > If OTOH you want your foo class to have sqrt, arccos, etc. methods
      > without defining them explicitly, I think you're looking for something
      > like:
      >
      > . import Numeric
      > .
      > . class Foo(object):
      > . def __init__(self, value):
      > . self.value = float(value)
      > . for u in ['sqrt', 'cos', 'tan']:
      > . setattr(self, u, lambda uf=getattr(Nume ric, u):
      > . uf(self.value + 42.0))
      >[color=green][color=darkred]
      > >>> f = Foo(7)
      > >>> f.sqrt()[/color][/color]
      > 7.0
      >
      > HTH
      > Rainer[/color]

      Comment

      • Steven Bethard

        #4
        Re: class factory example needed (long)

        Gary Ruben wrote:[color=blue]
        > OK, I've managed to get this to work with Rainer's method, but I
        > realised it is not the best way to do it, since the methods are being
        > added by the constructor, i.e. they are instance methods. This means
        > that every time a foo object is created, a whole lot of code is being
        > run. It would be better to do the same thing with class 'static'
        > methods, if this is possible, so that the methods are created just once.
        > Is this possible?[/color]

        See my comment on the recipe at:



        STeVe

        Comment

        • Kent Johnson

          #5
          Re: class factory example needed (long)

          Gary Ruben wrote:[color=blue]
          > OK, I've managed to get this to work with Rainer's method, but I
          > realised it is not the best way to do it, since the methods are being
          > added by the constructor, i.e. they are instance methods. This means
          > that every time a foo object is created, a whole lot of code is being
          > run. It would be better to do the same thing with class 'static'
          > methods, if this is possible, so that the methods are created just once.
          > Is this possible?[/color]

          Here is a solution using a metaclass:

          import Numeric

          class MetaFoo(type):
          def __init__(cls, name, bases, d):
          super(MetaFoo, cls).__init__(c ls, name, bases, d)
          for u in ['sqrt', 'cos', 'tan']:
          setattr(cls, u, lambda self, uf=getattr(Nume ric, u): uf(self.value + 42.0))


          class Foo(object):
          __metaclass__ = MetaFoo

          def __init__(self, value):
          self.value = float(value)

          f = Foo(7)
          print f.sqrt()


          Kent

          Comment

          • Gary Ruben

            #6
            Re: class factory example needed (long)

            Thanks Steven and Kent, both of your suggestions look good to me. I'll
            try both out and pick one.
            Gary

            Gary Ruben wrote:[color=blue]
            > OK, I've managed to get this to work with Rainer's method, but I
            > realised it is not the best way to do it, since the methods are being
            > added by the constructor, i.e. they are instance methods. This means
            > that every time a foo object is created, a whole lot of code is being
            > run. It would be better to do the same thing with class 'static'
            > methods, if this is possible, so that the methods are created just once.
            > Is this possible?
            > Gary[/color]

            Comment

            Working...