Access Class method and variable using self

♀尐吖头ヾ 提交于 2020-01-24 01:45:07

问题


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


回答1:


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.




回答2:


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



回答3:


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.



来源:https://stackoverflow.com/questions/45121614/access-class-method-and-variable-using-self

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!