On 05 Jul 2012 11:55:33 GMT Steven D'Aprano <steve+comp.lang.pyt...@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 -- http://mail.python.org/mailman/listinfo/python-list