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

Reply via email to