Question

Having a class

class A(object):
    z = 0

    def Func1(self):
        return self.z

    def Func2(self):
        return A.z

Both methods (Func1 and Func2) give the same result and are only included in this artificial example to illustrate the two possible methods of how to address z.

The result of Func* would only differ if an instance would shadow z with something like self.z = None.

What is the proper python way to access the class variable z using the syntax of Func1 or Func2?

Was it helpful?

Solution

I would say that the proper way to get access to the variable is simply:

a_instance.z  #instance variable 'z'
A.z           #class variable 'z'

No need for Func1 and Func2 here.


As a side note, if you must write Func2, it seems like a classmethod might be appropriate:

@classmethod
def Func2(cls):
    return cls.z

As a final note, which version you use within methods (self.z vs. A.z vs. cls.z with classmethod) really depends on how you want your API to behave. Do you want the user to be able to shadow A.z by setting an instance attribute z? If so, then use self.z. If you don't want that shadowing, you can use A.z. Does the method need self? If not, then it's probably a classmethod, etc.

OTHER TIPS

I would usually use self.z, because in case there are subclasses with different values for z it will choose the "right" one. The only reason not to do that is if you know you will always want the A version notwithstanding.

Accessing via self or via a classmethod (see mgilson's answer) also facilitates the creating of mixin classes.

If you don't care about value clobbering and things like that, you're fine with self.z. Otherwise, A.z will undoubtedly evaluate to the class variable. Beware, though, about what would happen if a subclass B redefines z but not Func2:

class B(A):
    z = 7

b = B()
b.Func2()  # Returns 0, not 7

Which is quite logical, after all. So, if you want to access a class variable in a, somehow, polymorphic way, you can just do one of the following:

self.__class__.z
type(self).z

According to the documentation, the second form does not work with old-style classes, so the first form is usually more comptaible across Python 2.x versions. However, the second form is the safest one for new-style classes and, thus, for Python 3.x, as classes may redefine the __class__ attribute.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top