Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Returning other instance from __init__ (http://www.velocityreviews.com/forums/t484423-returning-other-instance-from-__init__.html)

Paulo da Silva 03-15-2007 04:33 AM

Returning other instance from __init__
 
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

Alex Martelli 03-15-2007 05:21 AM

Re: Returning other instance from __init__
 
Paulo da Silva <psdasilvaX@esotericaX.ptX> 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

Dennis Lee Bieber 03-15-2007 05:28 AM

Re: Returning other instance from __init__
 
On Thu, 15 Mar 2007 04:33:01 +0000, Paulo da Silva
<psdasilvaX@esotericaX.ptX> 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
wlfraed@ix.netcom.com wulfraed@bestiaria.com
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: web-asst@bestiaria.com)
HTTP://www.bestiaria.com/

Paul Boddie 03-15-2007 11:36 AM

Re: Returning other instance from __init__
 
On 15 Mar, 06:21, a...@mac.com (Alex Martelli) wrote:
> Paulo da Silva <psdasil...@esotericaX.ptX> 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


Alex Martelli 03-15-2007 02:50 PM

Re: Returning other instance from __init__
 
Paul Boddie <paul@boddie.org.uk> 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

Paulo da Silva 03-15-2007 02:54 PM

Re: Returning other instance from __init__
 
Alex Martelli escreveu:
> Paulo da Silva <psdasilvaX@esotericaX.ptX> 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

Paul Boddie 03-15-2007 03:02 PM

Re: Returning other instance from __init__
 
On 15 Mar, 15:50, a...@mac.com (Alex Martelli) wrote:
> Paul Boddie <p...@boddie.org.uk> 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


Alex Martelli 03-16-2007 02:59 AM

Re: Returning other instance from __init__
 
Paulo da Silva <psdasilvaX@esotericaX.ptX> wrote:

> Alex Martelli escreveu:
> > Paulo da Silva <psdasilvaX@esotericaX.ptX> 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

Paulo da Silva 03-16-2007 08:17 PM

Re: Returning other instance from __init__
 
Paulo da Silva escreveu:
> Alex Martelli escreveu:
>> Paulo da Silva <psdasilvaX@esotericaX.ptX> 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.

Paulo da Silva 03-17-2007 01:05 AM

Re: Returning other instance from __init__ - I need help
 
Paulo da Silva escreveu:
> Paulo da Silva escreveu:
>> Alex Martelli escreveu:
>>> Paulo da Silva <psdasilvaX@esotericaX.ptX> 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.




All times are GMT. The time now is 10:19 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.