Re: cause __init__ to return a different class?
On Sep 15, 1:54 am, Ryan Kelly r...@rfk.id.au wrote: To be friendlier to others reading your code, I would consider using a classmethod to create an alternative constructor: I finally got back to looking at this today. As it turns out, un- overriding __new__ in the child class is more complicated than I first expected, and isn't worth the extra effort. So, I ended up using a constructor class method as you suggested. Thanks again! -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On Thu, 15 Sep 2011 03:20 pm Matthew Pounsett wrote: I'm wondering if there's a way in python to cause __init__ to return a class other than the one initially specified. My use case is that I'd like to have a superclass that's capable of generating an instance of a random subclass. You need to override the constructor, not the initializer. By the time __init__ is called, the instance has already been created. I've tried both returning the subclass (as I would when overloading an operator) but I get the complaint that __init__ wants to return None instead of a type. The other thing I tried was overwriting 'self' while inside __init__ but that doesn't seem to work either. No, because self is just an ordinary local variable. Overwriting self just changes the local variable, not the instance. However, you can sometimes modify the instance's class. One sometimes useful trick is something like this: class Test(object): def __init__(self): if condition(): self.__class__ = AnotherClass which will work, and is supported, so long as Test class and AnotherClass are compatible. (If they're not compatible, you'll get an exception.) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
Perhaps a more idiomatic way of achieving the same thing is to use a factory function, which returns instances of different classes: def PersonFactory(foo): if foo: return Person() else: return Child() Apologies if the code is messed up, I'm posting from Google groups web UI. -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On Sep 15, 1:35 am, Chris Rebert c...@rebertia.com wrote: Override __new__() instead: http://docs.python.org/reference/datamodel.html#object.__new__ Aha.. thanks! The reference book I'm working from neglects to mention __new__, so I'd assumed __init__ was the constructor. It hadn't occurred to me that python would separate the functions (I still don't see exactly why it would be useful to do that, but perhaps insight will come with time). -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On Sep 15, 1:54 am, Ryan Kelly r...@rfk.id.au wrote: The above will do exactly what you want, but it's generally bad style unless you have a very specific use-case. Is there a particular reason you need to magically return a subclass, rather than making this explicit in the code? To be friendlier to others reading your code, I would consider using a classmethod to create an alternative constructor: Yeah, I was considering doing this as well, particularly if I couldn't have made the other work. The reason I'm not too concerned about anyone misinterpreting what's going on is that in this case the base class is actually named for being a constructor, and any rare case where I want a specific subclass the subclass will be created directly. Thanks very much for your help! -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
I'd go for a factory function (http://en.wikipedia.org/wiki/Factory_method_pattern): def create(foo): return Child(foo) if foo else Parent() -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On 15 September 2011 15:41, Matthew Pounsett matt.pouns...@gmail.com wrote: On Sep 15, 1:35 am, Chris Rebert c...@rebertia.com wrote: Override __new__() instead: http://docs.python.org/reference/datamodel.html#object.__new__ Aha.. thanks! The reference book I'm working from neglects to mention __new__, so I'd assumed __init__ was the constructor. It hadn't occurred to me that python would separate the functions (I still don't see exactly why it would be useful to do that, but perhaps insight will come with time). If you're interested in the reason, I suggest you read Guido's essay on new style classes which were introduced in Python 2.2 (and are now a good 10 years old I think): http://www.python.org/download/releases/2.2.3/descrintro -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
cause __init__ to return a different class?
I'm wondering if there's a way in python to cause __init__ to return a class other than the one initially specified. My use case is that I'd like to have a superclass that's capable of generating an instance of a random subclass. I've tried both returning the subclass (as I would when overloading an operator) but I get the complaint that __init__ wants to return None instead of a type. The other thing I tried was overwriting 'self' while inside __init__ but that doesn't seem to work either. class Parent(object): def __init__(self, foo): if foo == True: self = Child(foo) class Child(Parent): def __init__(self, foo): pass Is there a way to do this? -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On Wed, Sep 14, 2011 at 10:20 PM, Matthew Pounsett matt.pouns...@gmail.com wrote: I'm wondering if there's a way in python to cause __init__ to return a class other than the one initially specified. My use case is that I'd like to have a superclass that's capable of generating an instance of a random subclass. snip Is there a way to do this? Override __new__() instead: http://docs.python.org/reference/datamodel.html#object.__new__ Cheers, Chris -- http://mail.python.org/mailman/listinfo/python-list
Re: cause __init__ to return a different class?
On 15/09/11 15:35, Chris Rebert wrote: On Wed, Sep 14, 2011 at 10:20 PM, Matthew Pounsett matt.pouns...@gmail.com wrote: I'm wondering if there's a way in python to cause __init__ to return a class other than the one initially specified. My use case is that I'd like to have a superclass that's capable of generating an instance of a random subclass. snip Is there a way to do this? Override __new__() instead: http://docs.python.org/reference/datamodel.html#object.__new__ The above will do exactly what you want, but it's generally bad style unless you have a very specific use-case. Is there a particular reason you need to magically return a subclass, rather than making this explicit in the code? To be friendlier to others reading your code, I would consider using a classmethod to create an alternative constructor: class MyBaseClass(object): @classmethod def get_random_subclass(cls, *args, **kwds) subcls = random.choice(cls.__subclasses__()) return subcls(*args, **kwds) To me, this reads pretty cleanly and makes it obvious that something unusual is going on: obj = MyBaseClass.get_random_subclass() While this hides the intention of the code and would require additional documentation or comments: obj = MyBaseClass() # note: actually returns a subclass! Just a thought :-) Cheers, Ryan -- Ryan Kelly http://www.rfk.id.au | This message is digitally signed. Please visit r...@rfk.id.au| http://www.rfk.id.au/ramblings/gpg/ for details signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list