Mike Orr wrote:
On Jun 5, 8:40 am, Gabriel Rossetti <[EMAIL PROTECTED]>
wrote:
Hello everyone,
I had read somewhere that it is preferred to use
self.__class__.attribute over ClassName.attribute to access class (aka
static) attributes. I had done this and it seamed to work, until I
subclassed a class using this technique and from there on things started
screwing up. I finally tracked it down to self.__class__.attribute! What
was happening is that the child classes each over-rode the class
attribute at their level, and the parent's was never set,
That's a misunderstanding of classes vs instances. If you have an
instance of MyClass(Superclass), there is one instance but several
classes. The instance is of MyClass; there is no instance of
Superclass. 'self' has a .__class__ attribute because it's an
instance, but MyClass and Superclass do not because they're already
classes.
Yes, I know that
Going further, self.a retrieves the instance attribute if it exists,
or or MyClass.a if it doesn't, or Superclass.a if that doesn't. But
assigning to self.a always assigns to an instance attribute. To
assign a class attribute you must use .__class__ or TheClass.
Likewise, to retrieve a class attribute that has been overridden by a
subclass or instance, you must use .__class__ or TheClass.
There's a very good reason to use self.__class__: it makes it possible
to subclass your class. In Jason Orendorff's path.py, some path
methods return new path objects. He uses 'path()' rather than
self.__class__ to construct these. So if you subclass 'path' to
extend it, these methods return path objects rather than your subclass
objects. In my Unipath package which was written later, I use
self.__class__ in these cases to allow users to extend my class.
Ok, I see a use for that now, I also tried a minimal example of my
problem and it worked as I expected, and thus I am unable to reproduce
my problem outside of my code. It may be linked to the fact that I am
using Zope interfaces and Tisted's plugin mechanism, as this problem was
born in that context ; it's possible that something happens in the
background that makes it behave strangely. Basically, I the base class
for the plugins create a class attribute of an object that is a mutex
and each subclass solicited it for access to the I/O. The class
attribute was created only once in it's __init__ (using a conditional
test). After running it though a debugger, I saw that in reality, every
Child instantiated it, so every child had it's own mutex, thus they
could each access the I/O even if it was "supposed" to be locked. I had
been using "self.__class__.myMutex" everywhere, so I changed it to
"MyClass.myMutex" and the code behaved correctly. This is what prompted
me to write this thread. As i said before, I tried reproducing the
problem out of context, with just regular classes, no interfaces &
plugin mechanism, and it works as I had expected (originally).
It's a little annoying that if you want to print a class's name in
some unknown object, you have to use obj.__class__.__name__ if it's an
instance, and obj.__name__ if it's a class. I sometimes wish classes
had a .__class__ attribute that's the class itself, but I can see how
that would cause its own confusion (and recursion).
Yes :-)
-- Mike Orr <[EMAIL PROTECTED]>
--
http://mail.python.org/mailman/listinfo/python-list
Gabriel
--
http://mail.python.org/mailman/listinfo/python-list