extend class: include factories functions inside constructor
Peter Otten
__peter__ at web.de
Thu Aug 18 10:45:34 EDT 2011
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...
More information about the Python-list
mailing list