Edward d'Auvergne wrote:
On 3/16/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
On Fri, 2007-03-16 at 01:50 +1100, Edward d'Auvergne wrote:
> On 3/16/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
> > On Fri, 2007-03-16 at 01:00 +1100, Edward d'Auvergne wrote:
> > > On 3/15/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
> > > > On Thu, 2007-03-15 at 00:09 +1100, Edward d'Auvergne wrote:
> > > > > On 3/14/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
> > > > > > On Tue, 2007-03-13 at 19:51 +1100, Edward d'Auvergne wrote:
> > > > > > > Gary,
> > > > > > >
> > > > > > > I've written some unit tests which are located in the file
> > > > > > > 'test_suite/unit_tests/data/__init__.py'. Would you
know what
> > > > > > > modifications I need to apply to make these tests run?
These tests
> > > > > > > are for the methods of the Data singleton class (the
relax data
> > > > > > > storage object) which is located in
'data/__init__.py'. I haven't
> > > > > > > used the statement 'from x import Data' for this class
so it is the
> > > > > > > legal and ubiquitous usage of an __init__.py file. Would
> > > > > > > 'unit_test_runner.py' handle this code?
> > > > > > >
> > > > > > > Thanks,
> > > > > > >
> > > > > > > Edward
> > > > > > >
> > > > > > >
> > > > > > > P.S. These tests demonstrate the utility of
subclassing the singleton
> > > > > > > and is one reason I was arguing for the use of the
class import rather
> > > > > > > than reference import.
> > > > > > >
> > > > > >
> > > > > > It is of course correct that the Singleton implimentation
I proposed
> > > > > > does not allow for subclassing. This however might well
be seen as a
> > > > > > design feature, given the well known conceptual problems
with
> > > > > > subclassing Singleton. Essentially, subclassing violates
the Singleton
> > > > > > Design Pattern:
> > > > > >
> > > > > > class Singleton:
> > > > > > def __new__(self):
> > > > > > ...
> > > > > >
> > > > > > class Sub(Singleton): pass
> > > > > >
> > > > > > >>> a = Singleton()
> > > > > > >>> b = Sub()
> > > > > > >>> isinstance(a,Singleton)
> > > > > > True
> > > > > > >>> isinstance(b,Singleton)
> > > > > > True
> > > > > > >>> a is b
> > > > > > False
> > > > > > >>> a == b
> > > > > > False
> > > > > >
> > > > > > ie. we have 2 instances of Singleton that are not the
same thing, and
> > > > > > not even equal! If this is the behaviour you want, then
you need
> > > > > > something other than Singleton. On the other hand, if you
really want
> > > > > > Singleton, then you can't also hope for subclassability.
> > > > >
> > > > > Actually one is an instance of Singleton and the other is
an instance
> > > > > of Sub.
> > > >
> > > > The definition of inheritance is that an instance of the
subclass is
> > > > also an instance of the parent class. ie. b is an instance of
both Sub
> > > > and Singleton. Inheritance from a Singleton class is
therefore a logical
> > > > contradiction.
> > >
> > > That is actually incorrect!
> >
> > Sorry to drag this on, but I'm not incorrect here, and its a fairly
> > fundamental point of OO philosophy and practice that is well worth
> > getting right. This is pasted directly from my Python command
line (the
> > interpreter does not lie!):
> >
> > >>> class A: pass
> > ...
> > >>> class B(A): pass
> > ...
> > >>> a= A()
> > >>> b = B()
> > >>> isinstance(a,A)
> > True
> > >>> isinstance(a,B)
> > False
> > >>> isinstance(b,B)
> > True
> > >>> isinstance(b,A)
> > True
> >
> > Because B is a subclass of A, all instances of B are also
instances of A
>
> The 'isinstance()' built-in function will return true if object x is
> an instance of the supplied class or, importantly, a subclass. This
> is what it's docstring says. Try the following instead (after
> reissuing the above statements):
>
> >>> a is b
> False
> >>> hash(a)
> -1217311764
> >>> hash(b)
> -1214788020
> >>> id(a)
> -1217311764
> >>> id(b)
> -1214788020
>
> If b was the same instance as a, then the first statement would return
> true. The two hash() statements show that a and b are different. The
> two id() statements show that they occupy different locations in
> memory - the number is the object's memory address. Another test is
> populating the empty containers:
>
> >>> a.x = 1
> >>> b.y = 2
> >>> dir(a)
> ['__doc__', '__module__', 'x']
> >>> dir(b)
> ['__doc__', '__module__', 'y']
>
> The instances a and b are very much different!
This is all true, but misses the point. a and b are different objects,
but they are of the same type:
>>> type(a) is type(b)
True
They are necessarily the same type, both are <type 'instance'>.
yes but that isn't the class you need to look at object.__class__ and
object.__bases__ and so on resursivley...
and both of them are instances of the parent class A. So to go back to
where we started: for almost any implimentation of Singleton
Both are not instances of A. The Python builtin function
'isinstance()' is poorly named. It returns True if object b is an
instance of class B. But it also returns true if object b is an
instance of class B which is subclassed from A (isinstance(b, A)).
Note that there is no reference to an instance of A in this second
test, either here or when typing 'help(isinstance)').
I beg to disagree, it isn't (however type is ;-)) It does exactly what
is says on the packet
if you have class A and class B(A)
and instances a and b thereof
a is an A
and b is an A and a B
>>> single = Singleton()
>>> class Sub(Singleton): pass
...
>>> sub = Sub()
>>> isinstance(sub,Singleton)
True
This is the second part of the isinstance test, seeing if sub is and
instance of some class which is itself subclassed from Singleton.
>>> isinstance(single,Singleton)
True
This is the first part of the isinstance test, the actual testing if
it is an instance.
>>> sub is single
False
This breaches the Singleton design because we have two *different*
objects that are both instances of the Singleton class.
WRONG!!! We now have two different singletons! They occupy different
memory addresses and will have different contents. For example one
dictionary type can be the relax data storage object and the other can
be an object storing the various components used in the chi-squared
equation, relaxation equations, spectral density values, and geometric
components all calculated by the module 'maths_fns.mf'. Both these
two objects benefit by being singletons - the alternative currently
used by 'maths_fns.mf' is to pass a single data object into the
hundreds of functions which use that object.
NO... you have two object ot type Singleton i.e. sub.__base__==singleton
it is a singleton as is single.__class__ both can be accepted in the
sample place and behave the same way this breaks the contract for
anything that is is a singleton. There can only be one instance of
singleton within the interpreter. You can never have two singletons
which share the same type other than being an object.
To put this in terms of the favourite metaphore, because apple is a
subclass of fruit, all apples are also fruits (ie. all instances of
class Apple in also instances of class Fruit). Even if you have several
different apples, this does not make them any less fruity.
[snip to the chase]
I don't know where to start quite. Chris's explanation is clear (and
correct).
If one class derives from another it has an is a or inheritance contract.
An apple is a fruit, a fruit is a fruit and a pear is a fruit. any where
you accept a fruit you have to accpet apples pears or straight fruit.
Now the singleton pattern is behavioural not inheritance based. For each
class you call a singleton there can only be one instance of that type
in memory. So if you can have a print queue singleton there can only
ever be __one__ instance of a print queue singleton in memory. i.e. only
one memory address is associated with the class print queue. if you
subclass print queue to give you say an advanced print queue any object
is of type advanced print queue is a print queue and and an advanced
print queue all at the same time. now print queue was a singleton and so
must advanced print queue be. so again there can only be one memory
location associated with type advanced print queue and print queue. If
you make an instance of print queue which is not and advanced print
queue while you have an instance of advanced print queue in memory you
have broken the contract.
Lets take it one step further. Now consider if you sub class print
queue again to give a dumb print queue. That object is a print queue and
a dumb print queue all at the same time. A print queue is a singleton
and so must be a dumb print queue. If you create an object of dumb print
queue no other memory location other than that __instance__ may be
associated with a print queue or an advanced print queue (which by its
inheritance relationsship to print queue has __to be a print queue__) .
As soon as you create another isntance of either of these you break the
singleton contract because otf the inheritance contract. Except under
very strict conditions there is a very big impedance mismatch between
singleton and inheritance (which I can go into if need be).
I am pretty secure with my undertanding of inheritance and this pattern
and it is just one of those unavoidable thing. If you label something as
a singleton and there can only ever be one instance of that type in
memory. Anything you call a singleton must be the only instance of that
type in memory whehter it is of that type directly or because you can
follow an ineritance relationhsip to it.
It would somethimes be nice two have to fermions that could both
occupied the same space (ever wanted to walk through a wall when someone
was cross at you) but they can't (tip you hat to mr pauli) they just are
not made that way and the same goes here!
regards
gary
Edward
P.S. For those still following this thread, this argument is not
related to what was voted upon :)
_______________________________________________
relax (http://nmr-relax.com)
This is the relax-devel mailing list
relax-devel@xxxxxxx
To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-devel
.
--
-------------------------------------------------------------------
Dr Gary Thompson
Astbury Centre for Structural Molecular Biology,
University of Leeds, Astbury Building,
Leeds, LS2 9JT, West-Yorkshire, UK Tel. +44-113-3433024
email: garyt@xxxxxxxxxxxxxxx Fax +44-113-2331407
-------------------------------------------------------------------