Re: How to use "__new__"?

2005-03-29 Thread Steven Bethard
could ildg wrote:
As there is already __init__, why need a __new__?
What can __new__ give us while __init__ can't?
In what situations we should use __new__?
And in what situations we must use __new__?
Can __new__ take the place of __init__?
I believe the current documentation will be updated when 2.4.1 is 
released, but documentation for __new__ is now available at:

http://www.python.org/dev/doc/devel/ref/customization.html
In short, you could use __new__ in place of __init__, but it's probably 
only useful to do so if you need to change an instance *before* it's 
created.  In general, if you aren't subclassing an immutable type, and 
you're not sure that you need __new__, you probably don't.

STeVe
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to use "__new__"?

2005-03-29 Thread could ildg
Thank you.
I'm clear after I read the doc:
If __new__() returns an instance of cls, then the new instance's
__init__() method will be invoked like "__init__(self[, ...])", where
self is the new instance and the remaining arguments are the same as
were passed to __new__().

If __new__() does not return an instance of cls, then the new
instance's __init__() method will not be invoked.

__new__() is intended mainly to allow subclasses of immutable types
(like int, str, or tuple) to customize instance creation.


On Tue, 29 Mar 2005 18:12:41 -0700, Steven Bethard
<[EMAIL PROTECTED]> wrote:
> could ildg wrote:
> > As there is already __init__, why need a __new__?
> > What can __new__ give us while __init__ can't?
> > In what situations we should use __new__?
> > And in what situations we must use __new__?
> > Can __new__ take the place of __init__?
> 
> I believe the current documentation will be updated when 2.4.1 is
> released, but documentation for __new__ is now available at:
> 
> http://www.python.org/dev/doc/devel/ref/customization.html
> 
> In short, you could use __new__ in place of __init__, but it's probably
> only useful to do so if you need to change an instance *before* it's
> created.  In general, if you aren't subclassing an immutable type, and
> you're not sure that you need __new__, you probably don't.
> 
> STeVe
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to use "__new__"?

2005-03-29 Thread Heiko Wundram
Am Mittwoch, 30. März 2005 03:27 schrieb could ildg:
> Thank you.
> I'm clear after I read the doc:
> If __new__() returns an instance of cls, then the new instance's
> __init__() method will be invoked like "__init__(self[, ...])", where
> self is the new instance and the remaining arguments are the same as
> were passed to __new__().
>
> If __new__() does not return an instance of cls, then the new
> instance's __init__() method will not be invoked.
>
> __new__() is intended mainly to allow subclasses of immutable types
> (like int, str, or tuple) to customize instance creation.

Remember that __new__() can also be used to create singletons (to return a 
pre-existing instance in case some form of argument matches, for example):

class Singleton(object):
__buffer = {}

def __new__(cls,somearg):
if somearg not in cls.__buffer:
cls.__buffer[somearg] = super(cls,Singleton).__new__(cls)
return cls.__buffer[somearg]

def __init__(self,somearg):
self.__somearg = somearg

def __repr__(self):
return "" % (self.__somearg,hex(id(self)))

>>> x = Singleton(1)
>>> y = Singleton(2)
>>> z = Singleton(1)
>>> print x

>>> print y

>>> print z

>>> x is y
False
>>> x is z
True
>>> y is z
False

You could extend the above example quite easily to deal with deallocation (a 
reference to each created singleton is retained using the above class, 
always, as long as the program is running) and also to make it threadsafe or 
to disable initialization in case the singleton has already been initialized 
before.

-- 
--- Heiko.


pgpR2HcFvUtvj.pgp
Description: PGP signature
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: How to use "__new__"?

2005-03-29 Thread Heiko Wundram
Am Mittwoch, 30. März 2005 04:36 schrieb Heiko Wundram:
> You could extend the above example quite easily to deal with deallocation
> (a reference to each created singleton is retained using the above class,
> always, as long as the program is running) and also to make it threadsafe
> or to disable initialization in case the singleton has already been
> initialized before.

Just to post a complete example of a Singleton class which works in a 
multithreaded environment, and allows you to update future instances (a 
sample, untested implementation):


import threading
import weakref

class SingletonBase(object):
__buffer = {}
__bufferLock = threading.RLock()

def __new__(cls,*args,**kwargs):
cls.__bufferLock.acquire()
try:
inst = cls.__create_new__(buffer,*args,**kwargs)
if not hasattr(inst,"_SingletonBase__instanceLock"):
inst.__instanceLock = threading.RLock()
inst.__initialized = False
return inst
finally:
cls.__bufferLock.release()

@classmethod
def __create_new__(cls,*args,**kwargs):
return super(SingletonBase,cls).__new__(cls)

def __init__(self,*args,**kwargs):
self.__instanceLock.acquire()
try:
if not self.__initialized:
self.__initialize_new__(*args,**kwargs)
self.__initialized = True
else:
self.__update_old__(*args,**kwargs)
finally:
self.__instanceLock.release()

def __initialize_new__(self,*args,**kwargs):
pass

def __update_old__(self,*args,**kwargs):
pass

class Singleton(SingletonBase):

@classmethod
def __create_new__(cls,buffer,somearg):
inst = buffer.get(somearg,lambda: None)()
if inst is None:
inst = super(Singleton,cls).__create_new__(cls)
buffer[somearg] = weakref.ref(inst)
return inst

def __initialize_new__(self,somearg):
print "Initializing new instance."
self.__somearg = somearg

def __update_old__(self,somearg):
print "Updating old."
assert somearg == self.__somearg

# Initialize three singletons.
print "Creating singletons for 1, 2, 1."
x = Singleton(1)
y = Singleton(2)
z = Singleton(1)

# Print them out.
print "\nThree singletons: x, y, z."
print repr(x)
print repr(y)
print repr(z)

# Assert that x is not y, and x is z.
print "\nx is y, x is z"
print x is y
print x is z

# Delete names, and make sure weakrefs are unbound.
print "\nRemove all three singletons."
del x
del y
del z

# Recreate singleton for value 1.
print "\nRecreating singleton for value 1."
x = Singleton(1)
y = Singleton(1)

# Print them out.
print "\nNew Singleton(1): x, y."
print repr(x)
print repr(y)

# Check that x is y.
print "\nx is y"
print x is y


The above program prints the following output when run:


Creating singletons for 1, 2, 1.
Initializing new instance.
Initializing new instance.
Updating old.

Three singletons: x, y, z.
<__main__.Singleton object at 0xb7bfbc6c>
<__main__.Singleton object at 0xb7bfbcac>
<__main__.Singleton object at 0xb7bfbc6c>

x is y, x is z
False
True

Remove all three singletons.

Recreating singleton for value 1.
Initializing new instance.
Updating old.

New Singleton(1): x, y.
<__main__.Singleton object at 0xb7bfbc6c>
<__main__.Singleton object at 0xb7bfbc6c>

x is y
True


HTH!

-- 
--- Heiko.


pgpQKQoZkoCMz.pgp
Description: PGP signature
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: How to use "__new__"?

2005-03-29 Thread Terry Reedy

"could ildg" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
> __new__() is intended mainly to allow subclasses of immutable types
> (like int, str, or tuple) to customize instance creation.

Exactly.  It is an anwer to the conundrum: How do you give an immutable 
object its unchangeable value.  It is much like how to move an unmovable 
object to its permanent position ;-).

TJR



-- 
http://mail.python.org/mailman/listinfo/python-list