Access Class method and variable using self
Asked Answered
A

3

9

In below example Test class has two instance method and one classmethod

In set_cls_var_1 method I set class variable using self.

In set_cls_var_2 method I call class method using self.

   class Test():

        #class variable
        cls_var = 10

        def __init__(self):
           obj_var=20

        def set_cls_var_1(self,val):
            #second method to access class variable
            print "first "
            self.cls_var = val

        def set_cls_var_2(self):
            print "second"
            self.task(200)

        @classmethod
        def task(cls,val):
            cls.cls_var = val


t=Test()

#set class variable by first method
t.set_cls_var_1(100)

print Test.cls_var

#set class variable by second method
t.set_cls_var_2()

print Test.cls_var

Output

first 
10
second
200

Expected Output

first 
100
second
200

My question is: why only classmethod can call by self, Why not class variable

Axseed answered 15/7, 2017 at 18:47 Comment(3)
Assigning attributes on an instance will never assign to a class attribute.Lobation
But when I can access "cls_var" in "set_cls_var_1" like "print self.cls_var". why and how that possible, I don't understandAxseed
that mean i can only get class variable in instance method ,cant set class variable in instance method using selfAxseed
I
11

When you attempt to access an object's attribute using self, Python first searches the object's attributes. If it cannot find it there, then is searches the object's class's attributes. That is what's happening in your case;

Python first searches t's attributes. It doesn't find cls_var, so it then searches the T class's attributes. It finds cls_var so it stops, and returns cls_var's value.

However, when assigning attributes to self, Python always assigns them directly to the object, and never the object's class unless explicitly told to do so. That's why assinging self.cls_var to 100 didn't affect Test's cls_var attrbiute.

Inexcusable answered 15/7, 2017 at 19:6 Comment(2)
then why error when try to print cls.obj_var in class method if Python first searches the object's attributes. If it cannot find it there, then it searches the object's class's attributes.Axseed
@Axseed Because obj_var belongs to the object, not the class. Python raised an error because T does not have a obj_var, only the object's of T do.Inexcusable
A
8

I find something else that always use following way to access classmethod or variable in instance method

class Test():
    #class variable
    cls_var = 10

    def __init__(self):
        obj_var=20

    def set_cls_var_1(self,val):
        #first method to access class variable
        print "first type"
        cls = self.__class__
        cls.cls_var = val



t=Test()
#set class variable by first method

t.set_cls_var_1(100)

print Test.cls_var
Axseed answered 15/7, 2017 at 19:15 Comment(0)
H
2

When defining the Test class like you did, python creates a class object called Test which has an attribute cls_var equal to 10. When you instantiate this class, the created object doesn't have cls_var attribute. When calling self.cls_var it is actually the class' attribute that is retrieved due to the way python resolves attributes.

However when set self.cls_var the value is set at the object level! So further call to self.cls_var will give you the value of the object's attribute, and not the class' anymore!

Maybe this bit of code will make this clearer:

class A(object):
    a = 1
a = A()
print a.a  # prints 1
A.a = 2
print a.a  # prints 2

You see that even though when set the value at the class level, the changes are repercuted on the object, because, python will look up for the attribute in the class when it is not found at the object level.

When calling Test.cls_var it is the cls_var attribute of the class you are accessing! Not the one of the object you just modified.

Haase answered 15/7, 2017 at 19:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.