【问题标题】:Access Class method and variable using self使用 self 访问类方法和变量
【发布时间】:2017-12-20 15:43:59
【问题描述】:

在下面的例子中 Test 类有两个实例方法和一个类方法

set_cls_var_1 方法中,我使用 self 设置类变量。

set_cls_var_2 方法中,我使用 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

输出

first 
10
second
200

预期输出

first 
100
second
200

我的问题是: 为什么只有classmethod可以自己调用,为什么不是class变量

【问题讨论】:

  • 在实例上分配属性永远不会分配给类属性。
  • 但是当我可以像“print self.cls_var”一样访问“set_cls_var_1”中的“cls_var”时。为什么以及如何可能,我不明白
  • 这意味着我只能在实例方法中获取类变量,不能在实例方法中使用 self 设置类变量

标签: python python-2.7 class class-method class-variables


【解决方案1】:

当您尝试使用self 访问对象的属性时,Python 首先搜索对象的属性。如果在那里找不到它,则搜索对象的类的属性。这就是你的情况;

Python 首先搜索t 的属性。它没有找到cls_var,所以它然后搜索T 类的属性。它找到了cls_var,因此停止,并返回cls_var 的值。

但是,在将属性分配给self 时,Python 总是将它们直接分配给对象,而不是对象的类,除非明确告知这样做。这就是为什么将self.cls_var 分配给100 不会影响Testcls_var 属性。

【讨论】:

  • 如果 Python 首先搜索对象的属性,为什么在尝试在类方法中打印 cls.obj_var 时会出错。如果它在那里找不到它,那么它会搜索对象的类的属性。
  • @Kallz 因为obj_var 属于对象,而不是 . Python 引发错误,因为T 没有obj_var,只有T 的对象有。
【解决方案2】:

我发现其他东西总是使用以下方式访问实例方法中的类方法或变量

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】:

    像你一样定义 Test 类时,python 会创建一个名为 Test 的类对象,它的属性 cls_var 等于 10。当你实例化这个类时,创建的对象没有 cls_var 属性。当调用self.cls_var 时,实际上是由于python 解析属性的方式而检索到的类的属性。

    但是,当设置self.cls_var 时,该值是在对象级别设置的!因此,进一步调用 self.cls_var 将为您提供对象属性的值,而不是类的值!

    也许这段代码会让这个更清楚:

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

    您会看到,即使在类级别设置值,更改也会在对象上重新执行,因为当在对象级别找不到时,python会在类中查找属性。

    当调用Test.cls_var 时,它是您正在访问的类的cls_var 属性!不是您刚刚修改的对象之一。

    【讨论】:

      猜你喜欢
      • 2020-03-15
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多