Search code examples
pythonpython-2.7class-method

What is the first parameter of class methods in python?


According to my understanding, the first argument passed in a class method is the class itself where that class method is defined. So for example, consider the following code:

class A(object):
    __x=10

    @classmethod
    def clam(cls,*args):
        print(cls.__x)

class B(A):
    __x=50

And when i called :

B.clam()

the output was 10 which is OK as per my understanding because the class method being called is defined in class A, so class A will be passed implicitly to clam() and the value of __x there is 10.

But when i ran the following code:

class A(object):
    x=10

    @classmethod
    def clam(cls,*args):
        print(cls.x)

class B(A):
    x=50

and when i called:

 B.clam()

My life was suddenly ruined. The output is 50.

The only difference between both the cases is that x was private in former one.

What happened exactly? Why the output from the later one is 50 ? Was there any scope change or suddenly the first parameter passed to class method defined in A became class B ?


Solution

  • The first parameter in the class method is the class on which you are calling the method, not (necessarily) the class that defines the method. (Having a variable that always holds the same class would probably not be that useful.)

    In the first case, name mangling distinguishes the two fields, to protect you from accidentally shadowing private variables in a subclass. The field A.__x becomes A._A__x and B.__x becomes B._B__x. This ensures that you can't accidentally pick up a field in a subclass with a similar name to your private field in A. That's part of the reason name mangling exists.

    In the second case, there is no name mangling: you get the x field as defined in B, the class you are calling the method on.