By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,235 Members | 1,008 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,235 IT Pros & Developers. It's quick & easy.

ClassName.attribute vs self.__class__.attribute

P: n/a
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, so while I was
thinking that I had indeed a class attribute set in the parent, it was
the child's that was set, and every child had it's own instance! Since
it was a locking mechanism, lots of fun to debug... So, I suggest never
using self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!

I wish books and tutorials mentioned this explicitly....

Gabriel
Jun 27 '08 #1
Share this Question
Share on Google+
18 Replies


P: n/a
Gabriel Rossetti 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, so while I was
thinking that I had indeed a class attribute set in the parent, it was
the child's that was set, and every child had it's own instance! Since
it was a locking mechanism, lots of fun to debug... So, I suggest never
using self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!

I wish books and tutorials mentioned this explicitly....

Gabriel
If you define a class instance variable with the same name as the class
attribute, how would Python be able to distinguish the two? That is a feature
not a problem. Getter looks for instance attribute, if one is not found it
looks for a class attribute, and upwards. This behavior is used by Zope to do
all sorts of neat stuff.

-Larry Bates
Jun 27 '08 #2

P: n/a
On 5 juin, 17:40, Gabriel Rossetti <gabriel.rosse...@arimaz.com>
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.
It's even prefered to use self.attribute, unless you know you have
both an instance and a class attribute by the same name (but then if
you need to know which one you're accessing then you have a serious
design problem).
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,
Which is why it's prefered to access the attribute from the class (or
more simply from the instance which will get them from the class) - a
subclass may have extremly good reasons to have it's own instance of
the attribute.
and the parent's was never set,
This is another problem.
so while I was
thinking that I had indeed a class attribute set in the parent, it was
the child's that was set, and every child had it's own instance! Since
it was a locking mechanism, lots of fun to debug...
I can well believe it, and you do have my whole sympathy.
So, I suggest never
using self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!
I would not have expressed it that way. My own experience is that,
most of the time, you do know when it's ok for the subclasses to have
their own instance of the attribute and when it's not, so in the (very
rare) cases it's not ok you use __name_mangling.

Now I'd say that *unknowingly* overriding an attribute of your own
base class when you didn't expect it to happen is mostly a sign that
there's something you don't (didn't ?) quite get wrt/ lookup /
assignment / namespace etc rules in Python.
I wish books and tutorials mentioned this explicitly....
Possibly. OTHO, if you understand Python's lookup (name resolution)
rules, the difference between MyBaseClass.attrib and
self.__class__.attrib should be obvious. But this surely could be a
good example in a tutorial !-)
Jun 27 '08 #3

P: n/a
"br*****************@gmail.com" <br*****************@gmail.com>
writes:
On 5 juin, 17:40, Gabriel Rossetti <gabriel.rosse...@arimaz.com>
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.

It's even prefered to use self.attribute,
I was going to write exactly that, but it occurred to me that he might
want to be *assigning* to self.__class__.attribute (or
HisClass.attribute) from his methods, in which case self.attribute
would be quite different.
Jun 27 '08 #4

P: n/a
Larry Bates wrote:
Gabriel Rossetti 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, so while I was thinking that I had indeed a
class attribute set in the parent, it was the child's that was set,
and every child had it's own instance! Since it was a locking
mechanism, lots of fun to debug... So, I suggest never using
self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!

I wish books and tutorials mentioned this explicitly....

Gabriel

If you define a class instance variable with the same name as the
class attribute, how would Python be able to distinguish the two?
That is a feature not a problem. Getter looks for instance attribute,
if one is not found it looks for a class attribute, and upwards. This
behavior is used by Zope to do all sorts of neat stuff.

-Larry Bates
--
http://mail.python.org/mailman/listinfo/python-list

A class instance variable, you must mean an instance attribute no? If
that is so, then with just self.attribute? Maybe there is a concept that
I don't know about, I've studied class/static attributes and instance
attributes in my OOP classes.

Gabriel
Jun 27 '08 #5

P: n/a
Hrvoje Niksic a écrit :
"br*****************@gmail.com" <br*****************@gmail.com>
writes:
>On 5 juin, 17:40, Gabriel Rossetti <gabriel.rosse...@arimaz.com>
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.
It's even prefered to use self.attribute,

I was going to write exactly that, but it occurred to me that he might
want to be *assigning* to self.__class__.attribute (or
HisClass.attribute) from his methods, in which case self.attribute
would be quite different.
ACK.
Jun 27 '08 #6

P: n/a
Gabriel Rossetti a écrit :
Larry Bates wrote:
>Gabriel Rossetti 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, so while I was thinking that I had indeed a
class attribute set in the parent, it was the child's that was set,
and every child had it's own instance! Since it was a locking
mechanism, lots of fun to debug... So, I suggest never using
self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!

I wish books and tutorials mentioned this explicitly....

Gabriel

If you define a class instance variable with the same name as the
class attribute, how would Python be able to distinguish the two?
That is a feature not a problem. Getter looks for instance attribute,
if one is not found it looks for a class attribute, and upwards. This
behavior is used by Zope to do all sorts of neat stuff.

-Larry Bates
--
http://mail.python.org/mailman/listinfo/python-list

A class instance variable, you must mean an instance attribute no?
I think that's what he meant, yes.
If
that is so, then with just self.attribute? Maybe there is a concept that
I don't know about,
The concept of name resolution (aka lookup) rules in Python, perhaps ?
When you do obj.attribute, attribute is first looked for in the object,
then in it's class, then in the parent classes. So yes, you can get a
class (or parent class) attribute directly on the instance. Note that
assignment on the instance (obj.attribute = value) will alway (computed
attributes or other hooks excepted) create the attribute on the target,
so if you have Class.attribute set, and then do obj = Class();
obj.attribute = 42, then obj.attribute will shadow Class.attribute.
I've studied class/static attributes and instance
attributes in my OOP classes.
Forget about your OOP classes, mostly if it was in fact a Java or C++
class. Python's object model is very far away from what most courses
present as "OOP".
Gabriel
Jun 27 '08 #7

P: n/a
In article <ma*************************************@python.or g>,
Gabriel Rossetti <ga**************@arimaz.comwrote:
Larry Bates wrote:
Gabriel Rossetti 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, so while I was thinking that I had indeed a
class attribute set in the parent, it was the child's that was set,
and every child had it's own instance! Since it was a locking
mechanism, lots of fun to debug... So, I suggest never using
self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute, use
ClassName.attribute everywhere!
I shouldn't butt in since everyone else knows more about
this than I do, but it seems to me that saying you should
do this is wrong and saying you should do that is wrong -
which you should do depends on what you're trying to
accomplish.

There's something that comes up all the time in stuff
I do, where implicitly accessing self.__class__.attribute
is vital to make it work right. Say I have a Matrix class,
with an __add__ method:

class Matrix:
def __init__(self, data):
whatever
def __add__(self, other):
newdata = whatever
return Matrix(newdata)

The last line is almost surely not what I want (took
me a while, long ago, to figure this out). Because someday
when I have a subclass I want __add__ to return an instance
of the subclass. At first I thought I needed to rewrite the
last line to return SubClass(newdata). No, I simply return
self.__class__(newdata) and it works exactly the way I want.
I wish books and tutorials mentioned this explicitly....

Gabriel
If you define a class instance variable with the same name as the
class attribute, how would Python be able to distinguish the two?
That is a feature not a problem. Getter looks for instance attribute,
if one is not found it looks for a class attribute, and upwards. This
behavior is used by Zope to do all sorts of neat stuff.

-Larry Bates
--
http://mail.python.org/mailman/listinfo/python-list
A class instance variable, you must mean an instance attribute no? If
that is so, then with just self.attribute? Maybe there is a concept that
I don't know about, I've studied class/static attributes and instance
attributes in my OOP classes.

Gabriel
--
David C. Ullrich
Jun 27 '08 #8

P: n/a
On Jun 5, 8:40 am, Gabriel Rossetti <gabriel.rosse...@arimaz.com>
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.

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.

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).

-- Mike Orr <sl********@gmail.com>
Jun 27 '08 #9

P: n/a
Mike Orr wrote:
On Jun 5, 8:40 am, Gabriel Rossetti <gabriel.rosse...@arimaz.com>
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 <sl********@gmail.com>
--
http://mail.python.org/mailman/listinfo/python-list
Gabriel
Jun 27 '08 #10

P: n/a
Bruno Desthuilliers wrote:
Gabriel Rossetti a écrit :
>Larry Bates wrote:
>>Gabriel Rossetti 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, so while I was thinking that I had indeed a
class attribute set in the parent, it was the child's that was set,
and every child had it's own instance! Since it was a locking
mechanism, lots of fun to debug... So, I suggest never using
self.__class__.attribute, unless you don't mind it's children
overriding it, but if you want a truly top-level class attribute,
use ClassName.attribute everywhere!

I wish books and tutorials mentioned this explicitly....

Gabriel

If you define a class instance variable with the same name as the
class attribute, how would Python be able to distinguish the two?
That is a feature not a problem. Getter looks for instance
attribute, if one is not found it looks for a class attribute, and
upwards. This behavior is used by Zope to do all sorts of neat stuff.

-Larry Bates
--
http://mail.python.org/mailman/listinfo/python-list

A class instance variable, you must mean an instance attribute no?

I think that's what he meant, yes.
Ok.
>
>If that is so, then with just self.attribute? Maybe there is a
concept that I don't know about,

The concept of name resolution (aka lookup) rules in Python, perhaps ?
When you do obj.attribute, attribute is first looked for in the
object, then in it's class, then in the parent classes. So yes, you
can get a class (or parent class) attribute directly on the instance.
Note that assignment on the instance (obj.attribute = value) will
alway (computed attributes or other hooks excepted) create the
attribute on the target, so if you have Class.attribute set, and then
do obj = Class(); obj.attribute = 42, then obj.attribute will shadow
Class.attribute.
Not really, see my answer to Mike Orr's msg.
>I've studied class/static attributes and instance attributes in my
OOP classes.

Forget about your OOP classes, mostly if it was in fact a Java or C++
class. Python's object model is very far away from what most courses
present as "OOP".
Ok, in some ways yes.
>Gabriel
--
http://mail.python.org/mailman/listinfo/python-list

Jun 27 '08 #11

P: n/a
Mike Orr <sl********@gmail.comwrote:
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.
Classes are also instances, usually they are instances of the type 'type'
(and even 'type' is an instance of itself):
>>class SuperClass(object): pass
>>SuperClass.__class__
<type 'type'>
>>type(SuperClass)
<type 'type'>
>>type.__class__
<type 'type'>

Old style classes don't have a class attribute, but you shouldn't be using
old style classes anyway and so long as you use
type(x)
to access its class rather than accessing the __class__ attribute directly
that doesn't particularly matter.
--
Duncan Booth http://kupuguy.blogspot.com
Jun 27 '08 #12

P: n/a
Mike Orr <sl********@gmail.comwrites:
There's a very good reason to use self.__class__: it makes it
possible to subclass your class.
This really depends on the usage. In the OP's use case, he wanted the
subclasses to share the same lock object defined in the superclass
(because of synchronization), so it would have been wrong to use
self.__class__ *because* of subclassing.

Also note that for new-style classes, self.__class__ can be spelled as
type(self), since there is no distinction between classes and types.
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).
They do, the metaclass. :-)
Jun 27 '08 #13

P: n/a
Mike Orr a écrit :
(snip)
'self' has a .__class__ attribute because it's an
instance, but MyClass and Superclass do not because they're already
classes.
Not true for new-style classes:
>>class Toto(object): pass
....
>>Toto.__class__
<type 'type'>
(snip)
I sometimes wish classes
had a .__class__ attribute that's the class itself,
newstyle classes do have a class attribute, that refers to the metaclass.
but I can see how
that would cause its own confusion (and recursion).
FWIW, metaclasses do have a class attribute that refers to itself !-)

Jun 27 '08 #14

P: n/a
Bruno Desthuilliers <br********************@websiteburo.invalidwrote :
>
FWIW, metaclasses do have a class attribute that refers to itself !-)
One metaclass (i.e. type) has a class attribute that refers to itself.

Other metaclasses have a class attribute that refers to the metaclass's
metaclass. I can't think of any situation where a metaclass would be its
own metaclass except for 'type' itself, but then I think I've got a
headache trying to think about this so maybe I'm wrong.

In fact, thinking about it a bit more, I think that if you did have another
metaclass which is its own metaclass then the class cannot subclass
'object'.

--
Duncan Booth http://kupuguy.blogspot.com
Jun 27 '08 #15

P: n/a
Duncan Booth <du**********@invalid.invalidwrites:
In fact, thinking about it a bit more, I think that if you did have
another metaclass which is its own metaclass then the class cannot
subclass 'object'.
You could if the metaclass of your metaclass inherited from 'type'.
Then your types could still be binary-compatible with Python types,
and your objects with 'object'. It's difficult to envision what you'd
gain with a custom meta-meta-class, but it seems possible:
>>class MetaMeta(type): pass
....
>>class Meta(type):
.... __metaclass__ = MetaMeta
....
>>class Foo(object):
.... __metaclass__ = Meta
....
>>f = Foo()
f
<__main__.Foo object at 0xb7d27bec>
>>type(f)
<class '__main__.Foo'>
>>type(type(f))
<class '__main__.Meta'>
>>type(type(type(f)))
<class '__main__.MetaMeta'>
>>isinstance(f, object)
True
Jun 27 '08 #16

P: n/a
Duncan Booth wrote:
Mike Orr <sl********@gmail.comwrote:

>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.

Classes are also instances, usually they are instances of the type 'type'
(and even 'type' is an instance of itself):

Ok, I didn't know that
>>>class SuperClass(object): pass

>>>SuperClass.__class__
<type 'type'>
>>>type(SuperClass)
<type 'type'>
>>>type.__class__
<type 'type'>

Old style classes don't have a class attribute, but you shouldn't be using
old style classes anyway and so long as you use
type(x)
to access its class rather than accessing the __class__ attribute directly
that doesn't particularly matter.

Yes, I don't use old style classes
Jun 27 '08 #17

P: n/a
Duncan Booth a écrit :
Bruno Desthuilliers <br********************@websiteburo.invalidwrote :
>FWIW, metaclasses do have a class attribute that refers to itself !-)
One metaclass (i.e. type) has a class attribute that refers to itself.

Other metaclasses have a class attribute that refers to the metaclass's
metaclass. I can't think of any situation where a metaclass would be its
own metaclass except for 'type' itself, but then I think I've got a
headache trying to think about this
Yeps, same pattern here :-/

Thanks for the correction, anyway.
(snip)
Jun 27 '08 #18

P: n/a

"One metaclass (i.e. type) has a class attribute that refers to itself.
>
Other metaclasses have a class attribute that refers to the metaclass's
metaclass. I can't think of any situation where a metaclass would be its
own metaclass except for 'type' itself, but then I think I've got a
headache trying to think about this
In 3.0, with old classes gone and all classes called 'classes'*:

All objects are instances of base class 'object', nearly always indirectly
via subclasses of 'object'. All classes are subclasses of 'object',
including base metaclass 'type'. The methods of 'object' are the methods
that apply to objects as objects in general, as instances. Many of these
are 'base methods' that get overridden in subclasses to fit their
instances.

All classes (including object and type, dropping the quotes) are instances
of type, usually directly but occassionally via subclasses of type. In
other words, the subclass type defines the subclass of objects that are
classes. The additional attributes and methods of type (beyond those
inherited from object ) are, therefore, those that specifically apply to
all classes. These include __call__, by which classes (including 'object'
and 'type' itself) make instances.

The circularity conundrum is that type is a subclass of object while the
immutable class attribute of both object and type is type. The answer, of
course, is that a Python interpreter, as god of a Python universe, creates
both 'ex nihilo', from nothing, with the required attributes.

* In 3.0a5+
>>type(type)
<class 'type'# instead of <type 'type'>, and so on.

Terry Jan Reedy

Jun 27 '08 #19

This discussion thread is closed

Replies have been disabled for this discussion.