Access class variable from instance

I have this class:

class ReallyLongClassName:

    static_var = 5

    def instance_method(self):
        ReallyLongClassName.static_var += 1

Is there some way to access the static variable using the self variable? I’d rather do something like class(self).static_var += 1, because long names are unreadable.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use self.__class__.classAttr. This should work for both old & new style classes.

Method 2

The answer is “yes, but…”

The best way to understand is to actually try it:

>>> class RLCN:
...     static_var = 5
...     def method1(self):
...         RLCN.static_var += 1
...     def method2(self):
...         self.static_var += 1
>>> rlcn = RLCN()
>>> RLCN.static_var, rlcn.static_var
(5, 5)
>>> rlcn.static_var
5
>>> rlcn.method1()
>>> RLCN.static_var, rlcn.static_var
(6, 6)
>>> rlcn.method2()
>>> RLCN.static_var, rlcn.static_var
(6, 7)

What happened?

Well, accessing a class attribute through self works just fine. If there is no instance attribute of the same name, you get the class attribute.

But assigning to it will hide the class attribute with a new instance attribute of the same name. Which is probably not what you wanted.

Note that this means you can use class attributes as “default values” or “initial values” for instance attributes. But I’m not sure it’s very Pythonic to do so; what’s actually happening, and what a novice (especially someone coming from, e.g., C++11 or Java) thinks is happening, are very different.

(Things get slightly more complicated when you deal with descriptors, like methods or @propertys, but let’s ignore that; in the simple case that you’re discussing, it’s not relevant.)


I’d rather do something like class(self).static_var += 1, because long names are unreadable.

You can, you just need to spell it right: type is the function that returns the type of any object. So:

type(self).static_var += 1

This has the added advantage of being dynamic (e.g., when you have multiple inheritance and don’t know which side a @property comes from, you probably don’t want to explicitly list a class name, for basically the same reason you want to use super() instead of explicitly calling a base class method).

This has the disadvantage of not working on old-style classes in Python 2.x, but then you shouldn’t be using those anyway. Especially in classes that have a need for class attributes, because those are exactly the types you’re often going to later want to add @classmethods, @propertys, etc. to, and none of that works with old-style classes (along with many other things). If you really need to handle old-style and new-style classes transparently for some reason, self.__class__ is works with old-style classes. I’m not sure it’s guaranteed to work with new-style classes; the docs say that the return value of type(object) is “generally the same object as returned by object.__class__“, but doesn’t say under what conditions that “generally” is untrue. It’s also documented as a special attribute “added by the implementation” for “several object types” in 3.x. In practice, I don’t know of any cases where they’re different in 3.x, and in 2.x, the most prominent case where they’re different is old-style classes.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x