Creating an instance when the argument is already an instance.

Olive diolu at bigfoot.com
Fri Jul 6 10:01:24 EDT 2012


On 05 Jul 2012 11:55:33 GMT
Steven D'Aprano <steve+comp.lang.python at pearwood.info> wrote:

> On Thu, 05 Jul 2012 12:29:24 +0200, Olive wrote:
> 
> > I am learning python -:)
> > 
> > I am creating a new class: package (to analyse the packages
> > database in some linux distros). I have created a class package
> > such that package("string") give me an instance of package if
> > string is a correct representation of a package. I would like that
> > if pack is already an instance of package then package(pack) just
> > return pack.
> 
> The built-in types only do this for immutable objects, those which
> cannot be modified.
> 
> py> a = float('42.5')
> py> b = float(a)
> py> a is b
> True
> 
> 
> But note carefully that this is not a guarantee of the language.
> Other versions of Python may not do this.
> 
> Also note carefully that it is only immutable objects which do this. 
> Mutable objects do not behave this way:
> 
> py> a = ['a', 1, None]
> py> b = list(a)
> py> a is b
> False
> 
> 
> By default, most custom-made classes are mutable, and so re-using 
> instances is the wrong thing to do. Unfortunately, it is moderately 
> tricky to make mutable classes in Python. One way is described here:
> 
> http://northernplanets.blogspot.com.au/2007/01/immutable-instances-in-python.html
> 
> You can also look at the source code for Decimal (warning: it's BIG)
> or Fraction:
> 
> http://hg.python.org/cpython/file/2.7/Lib/decimal.py
> http://hg.python.org/cpython/file/2.7/Lib/fractions.py
> 
> 
> But suppose you make your class immutable. Then it's quite safe, and 
> easy, to get the behaviour you want:
> 
> 
> class Package(object):
>     def __new__(cls, argument):
>         if isinstance(argument, Package):
>             return argument
>         return object.__new__(cls, argument)
> 
> 
> or similar, I haven't actually tested the above. But the important
> trick is to use __new__, the constructor, rather than __init__, which
> runs after the instance is already created, and to use an isinstance
> test to detect when you already have an instance.
> 

Yes the trick with the __new__ works. We have to test afterwards i the
__init__ if the instance is already initialised and otherwise do
nothing. Thanks! I am learning and I didn't know the __new__ feature.

Olive



More information about the Python-list mailing list