Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Returning other instance from __init__

Reply
Thread Tools

Returning other instance from __init__

 
 
Paulo da Silva
Guest
Posts: n/a
 
      03-15-2007
I would like to implement something like this:

class C1:
def __init__(self,xxx):
if ... :
self.foo = foo
self.bar = bar
else:
self=C1.load(xxx)

def load(xxx):
...
return instance_of_C1
load=staticmethod(load)

This does not seem correct. How can I do it?

Thanks for any help
Paulo
 
Reply With Quote
 
 
 
 
Alex Martelli
Guest
Posts: n/a
 
      03-15-2007
Paulo da Silva <(E-Mail Removed)> wrote:

> I would like to implement something like this:
>
> class C1:
> def __init__(self,xxx):
> if ... :
> self.foo = foo
> self.bar = bar
> else:
> self=C1.load(xxx)
>
> def load(xxx):
> ...
> return instance_of_C1
> load=staticmethod(load)
>
> This does not seem correct. How can I do it?


Use __new__ for such purposes, not __init__. (You need to make C1
newstyle, e.g. inherit from object, to make special method __new__
work).

From __new__ you can return whatever you wish. However, if you return
an instance of C1, it _will_ be passed to __init__; so, just make sure
__init__ doesn't redo the initialization if passed an
already-initialized self.

E.g.:

class C1(object):
def __new__(cls, xxx):
if xxx: return type.__new__(cls, xxx)
else: return C1.load(xxx)
@staticmethod
def load(xxx): return ...whatever...
def __init__(self, xxx):
if hasattr(self, 'foo'): return
self.foo = 'foo'
self.bar = 'bar'


Alex
 
Reply With Quote
 
 
 
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      03-15-2007
On Thu, 15 Mar 2007 04:33:01 +0000, Paulo da Silva
<(E-Mail Removed)> declaimed the following in comp.lang.python:

> I would like to implement something like this:
>
> class C1:
> def __init__(self,xxx):
> if ... :
> self.foo = foo
> self.bar = bar
> else:
> self=C1.load(xxx)
>
> def load(xxx):
> ...
> return instance_of_C1
> load=staticmethod(load)
>
> This does not seem correct. How can I do it?
>

You can't do it with __init__()...

__init__() only INITIALIZES attributes of an object (self, passed
in) that is created by __new__().
--
Wulfraed Dennis Lee Bieber KD6MOG
http://www.velocityreviews.com/forums/(E-Mail Removed) (E-Mail Removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (E-Mail Removed))
HTTP://www.bestiaria.com/
 
Reply With Quote
 
Paul Boddie
Guest
Posts: n/a
 
      03-15-2007
On 15 Mar, 06:21, (E-Mail Removed) (Alex Martelli) wrote:
> Paulo da Silva <(E-Mail Removed)> wrote:
> >
> > I would like to implement something like this:
> >
> > class C1:
> > def __init__(self,xxx):
> > if ... :
> > self.foo = foo
> > self.bar = bar
> > else:
> > self=C1.load(xxx)
> >
> > def load(xxx):
> > ...
> > return instance_of_C1
> > load=staticmethod(load)
> >
> > This does not seem correct. How can I do it?

>
> Use __new__ for such purposes, not __init__. (You need to make C1
> newstyle, e.g. inherit from object, to make special method __new__
> work).


Call me a traditionalist, but why wouldn't a factory function be good
enough?

def C1(xxx):
if ...:
return the_real_C1()
else:
return load(xxx)

def load(xxx):
...
return instance_of_C1

Or perhaps seeing more special methods and decorators just puts me in
a grumpy mood. For me, the power of Python is derived from being
able to do things like making callables "constructors" whilst
providing some illusion that C1 (in this case) is a class.

Paul

 
Reply With Quote
 
Alex Martelli
Guest
Posts: n/a
 
      03-15-2007
Paul Boddie <(E-Mail Removed)> wrote:
...
> > > class C1:
> > > def __init__(self,xxx):

...
> > Use __new__ for such purposes, not __init__. (You need to make C1
> > newstyle, e.g. inherit from object, to make special method __new__
> > work).

>
> Call me a traditionalist, but why wouldn't a factory function be good
> enough?


That depends on whether you need name C1 to refer to a class, or not.

If you want name C1 to be usable outside this module as a class (to
subclass it, use with isinstance or issubclass, be available to an IDE's
classbrowser or other means of introspection including pydoc, etc), then
making name C1 refer to a function instead would not work.

> Or perhaps seeing more special methods and decorators just puts me in
> a grumpy mood. For me, the power of Python is derived from being
> able to do things like making callables "constructors" whilst
> providing some illusion that C1 (in this case) is a class.


For me, OTOH, it's not just smoke and mirrors (or as you say
"illusion"), there's also plenty of real power, and __new__ is part of
that. (Decorators however are just handy syntax -- they let you avoid
repeating one name three times, and avoiding repetition is a good thing,
but their real power is essentially that of higher-order-functions that
could of course be used with other syntax if need be).


Alex
 
Reply With Quote
 
Paulo da Silva
Guest
Posts: n/a
 
      03-15-2007
Alex Martelli escreveu:
> Paulo da Silva <(E-Mail Removed)> wrote:

....

>
> E.g.:
>
> class C1(object):
> def __new__(cls, xxx):
> if xxx: return type.__new__(cls, xxx)
> else: return C1.load(xxx)
> @staticmethod
> def load(xxx): return ...whatever...
> def __init__(self, xxx):
> if hasattr(self, 'foo'): return
> self.foo = 'foo'
> self.bar = 'bar'
>



Just for a better understanding ...
Can I do this?

class C1(object):
def __new__(cls, xxx):
if xxx:
cls.foo='foo'
cls.bar='bar'
return type.__new__(cls, xxx)
else:
return C1.load(xxx)
@staticmethod
def load(xxx): return ...whatever...
# OMMIT THE __init__
# or
def __init__(self, xxx):
pass
 
Reply With Quote
 
Paul Boddie
Guest
Posts: n/a
 
      03-15-2007
On 15 Mar, 15:50, (E-Mail Removed) (Alex Martelli) wrote:
> Paul Boddie <(E-Mail Removed)> wrote:
> > Call me a traditionalist, but why wouldn't a factory function be good
> > enough?

>
> That depends on whether you need name C1 to refer to a class, or not.


Right.

> If you want name C1 to be usable outside this module as a class (to
> subclass it, use with isinstance or issubclass, be available to an IDE's
> classbrowser or other means of introspection including pydoc, etc), then
> making name C1 refer to a function instead would not work.


True. I can easily buy the argument about wanting to subclass C1,
although you'd always have the real class available somewhere as well.
For things like IDEs, class browsers and so on, I think more work
needs to be done to make these things more "aware" - it sounds like
they expect a more rigid language (like Java), but I do have some
awareness of why it's tempting to let them operate on their current
level of introspection.

> > Or perhaps seeing more special methods and decorators just puts me in
> > a grumpy mood. For me, the power of Python is derived from being
> > able to do things like making callables "constructors" whilst
> > providing some illusion that C1 (in this case) is a class.

>
> For me, OTOH, it's not just smoke and mirrors (or as you say
> "illusion"), there's also plenty of real power, and __new__ is part of
> that.


Oh, I like the illusion! The illusion is what makes Python so
powerful, after all.

Paul

 
Reply With Quote
 
Alex Martelli
Guest
Posts: n/a
 
      03-16-2007
Paulo da Silva <(E-Mail Removed)> wrote:

> Alex Martelli escreveu:
> > Paulo da Silva <(E-Mail Removed)> wrote:

> ...
>
> >
> > E.g.:
> >
> > class C1(object):
> > def __new__(cls, xxx):
> > if xxx: return type.__new__(cls, xxx)
> > else: return C1.load(xxx)
> > @staticmethod
> > def load(xxx): return ...whatever...
> > def __init__(self, xxx):
> > if hasattr(self, 'foo'): return
> > self.foo = 'foo'
> > self.bar = 'bar'
> >

>
>
> Just for a better understanding ...
> Can I do this?
>
> class C1(object):
> def __new__(cls, xxx):
> if xxx:
> cls.foo='foo'
> cls.bar='bar'
> return type.__new__(cls, xxx)
> else:
> return C1.load(xxx)
> @staticmethod
> def load(xxx): return ...whatever...
> # OMMIT THE __init__
> # or
> def __init__(self, xxx):
> pass


Yes (omitting the __init__ is better than having it empty), but why do
you want to alter the class object itself, rather than the INSTANCE
you're returning?

I suspect what you really want to do is rather

if xxx:
newobj = type.__new__(cls)
newobj.foo = 'foo'
newobj.bar = 'bar'
return newobj
else ...etc etc...

altering the _instance_ and not the _class_ itself.


Alex
 
Reply With Quote
 
Paulo da Silva
Guest
Posts: n/a
 
      03-16-2007
Paulo da Silva escreveu:
> Alex Martelli escreveu:
>> Paulo da Silva <(E-Mail Removed)> wrote:

> ....
>
>> E.g.:
>>
>> class C1(object):
>> def __new__(cls, xxx):
>> if xxx: return type.__new__(cls, xxx)
>> else: return C1.load(xxx)
>> @staticmethod
>> def load(xxx): return ...whatever...
>> def __init__(self, xxx):
>> if hasattr(self, 'foo'): return
>> self.foo = 'foo'
>> self.bar = 'bar'
>>

>
>
> Just for a better understanding ...
> Can I do this?
>
> class C1(object):
> def __new__(cls, xxx):
> if xxx:
> cls.foo='foo'
> cls.bar='bar'
> return type.__new__(cls, xxx)

This does not work(!) at least for python 2.4.3.

> else:
> return C1.load(xxx)
> @staticmethod
> def load(xxx): return ...whatever...
> # OMMIT THE __init__
> # or
> def __init__(self, xxx):
> pass


I needed return cls and put the __init__ stuff here.
Is this the best practice?

Thanks.
 
Reply With Quote
 
Paulo da Silva
Guest
Posts: n/a
 
      03-17-2007
Paulo da Silva escreveu:
> Paulo da Silva escreveu:
>> Alex Martelli escreveu:
>>> Paulo da Silva <(E-Mail Removed)> wrote:

>> ....
>>
>>> E.g.:
>>>
>>> class C1(object):
>>> def __new__(cls, xxx):
>>> if xxx: return type.__new__(cls, xxx)
>>> else: return C1.load(xxx)
>>> @staticmethod
>>> def load(xxx): return ...whatever...
>>> def __init__(self, xxx):
>>> if hasattr(self, 'foo'): return
>>> self.foo = 'foo'
>>> self.bar = 'bar'
>>>

>>
>> Just for a better understanding ...
>> Can I do this?
>>
>> class C1(object):
>> def __new__(cls, xxx):
>> if xxx:
>> cls.foo='foo'
>> cls.bar='bar'
>> return type.__new__(cls, xxx)

> This does not work(!) at least for python 2.4.3.
>
>> else:
>> return C1.load(xxx)
>> @staticmethod
>> def load(xxx): return ...whatever...
>> # OMMIT THE __init__
>> # or
>> def __init__(self, xxx):
>> pass

>
> I needed return cls and put the __init__ stuff here.
> Is this the best practice?
>


When debugging, I found this is wrong!!!
Would someone please clarify what do I have to return from
__new__?

Thank you very much.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Should one always add super().__init__() to the __init__? Ramchandra Apte Python 17 09-30-2012 12:04 PM
ancestor class' __init__ doesn't call other methods Luis P. Mendes Python 3 09-15-2006 10:10 PM
super(...).__init__() vs Base.__init__(self) Kent Johnson Python 7 02-12-2006 08:59 PM
__new__ does not call __init__ as described in descrintro.html (WAS:Can __new__ prevent __init__ from being called?) Steven Bethard Python 2 02-16-2005 06:50 AM
Accessing an instance's __init__ args from outside the class Alexander Eberts Python 3 07-15-2003 10:29 PM



Advertisments