extend class: include factories functions inside constructor
aspineux
aspineux at gmail.com
Thu Aug 18 11:09:43 EDT 2011
On Aug 18, 4:45 pm, Peter Otten <__pete... at web.de> wrote:
> aspineux wrote:
> > Hi
> > I have a closed class and 2 factories function
>
> > class Data:
> > def __init__(self):
> > self.payload=None
>
> > def data_from_string(payload):
> > data=Data()
> > data.payload=payload
> > return data
>
> > def data_from_file(f):
> > data=Data()
> > data.payload=f.read()
> > return data
>
> > And I want to extend the class, by first including the factories
> > function inside the constructor,
> > second add some method to the class.
>
> > class MyData(Data):
>
> > def __init__(self, arg):
> > # I know this coke is not working, this is to show you
> > # what I expect
> > if isinstance(arg, file):
> > self=data_from_file(arg)
> > else:
> > self=data_from_string(arg)
> > return self
>
> > def len(self):
> > return len(self.payload)
>
> > And how I want to use it
>
> >>>> m=MyData('hello')
> >>>> print m.len()
> > 5
>
> > any idea ?
>
> Assuming that Data is an oldstyle class you can either copy the Data
> instance's state
>
> class MyData(Data):
> def __init__(self, arg):
> if hasattr(arg, "read"):
> factory = data_from_file
> else:
> factory = data_from_string
> obj = factory(arg)
> self.__dict__.update(obj.__dict__)
>
> def __len__(self):
> return len(self.payload)
>
> or use another factory function and manually set the __class__:
>
> class MyData(Data):
> def __len__(self):
> return len(self.payload)
>
> def make_mydata(arg):
> if hasattr(arg, "read"):
> factory = data_from_file
> else:
> factory = data_from_string
> obj = factory(arg)
> obj.__class__ = MyData
> return obj
>
> If Data were a newstyle class you could move the hand-made polymorphism into
> the __new__() method:
>
> class MyData(Data):
> def __new__(class_, arg):
> if hasattr(arg, "read"):
> factory = data_from_file
> else:
> factory = data_from_string
> obj = factory(arg)
> obj.__class__ = class_
> return obj
> def __init__(self, arg):
> pass
> def __len__(self):
> return len(self.payload)
>
> if __name__ == "__main__":
> m = MyData("hello")
> print len(m)
>
> Nothing of the above strikes me as pretty. Perhaps we could come up with a
> neater solution if you tell us more about your use-case...
Ops, I clicked send before to finish my post.
Thanks for your quick and very valuable answer.
More information about the Python-list
mailing list