【问题标题】:Why is class variable accessible via class instance? [duplicate]为什么类变量可以通过类实例访问? [复制]
【发布时间】:2018-01-05 10:47:16
【问题描述】:

我创建了没有实例变量的类Circle。我添加了一个类方法from_diameter 来生成具有给定直径的圆。

class Circle:

    @classmethod
    def from_diameter(cls, diameter):
        cls.diameter = diameter
        return cls

diameter 是一个类(静态)变量。但是 - 看起来它也作为实例变量和类变量存在。

myCircle = Circle.from_diameter(10)
print Circle.diameter
print myCircle.diameter

输出:

10
10

它为什么有效?没有实例变量diameter。 我想print myCircle.diameter 应该会抛出一个错误。

【问题讨论】:

  • 通过类实例查找类变量与在实例上调用类方法时完全一样。换句话说,除非它们以这种方式工作,否则类将完全无用。

标签: python static-methods instance-variables class-method


【解决方案1】:

没有实例变量,只是 Python 对象中的名称查找首先查找实例,然后,如果未找到匹配项,则查找类。

类实例

类实例是通过调用类对象来创建的(见上文)。类实例有一个作为字典实现的命名空间,这是搜索属性引用的第一个位置。如果在那里找不到属性,并且实例的类具有该名称的属性,则使用类属性继续搜索。 [...] 如果没有找到类属性,并且对象的类具有 __getattr__() 方法,则调用该方法以满足查找。

(Python 2, Python 3)

【讨论】:

    【解决方案2】:

    当你尝试使用一个类访问变量时,它只会查看

    cls.__dict__
    

    但是当你尝试使用实例访问变量时,它看起来首先

    self.__dict__ 
    

    如果找到则返回,或者如果找不到,则它也会在中查找

    cls.__dict__
    

    这里 cls 是类

    class Test:
        temp_1=10
        temp_2=20
    
        def __init__(self):
            self.test_1=10
            self.test_2=20
    
        @classmethod
        def c_test(cls):
            pass
    
        def t_method(self):
            pass
    
    
    print Test.__dict__
    print Test().__dict__
    

    输出

    {'c_test': <classmethod object at 0x7fede8f35a60>, '__module__': '__main__', 't_method': <function t_method at 0x7fede8f336e0>, 'temp_1': 10, '__doc__': None, '__init__': <function __init__ at 0x7fede8f335f0>, 'temp_2': 20}
    
    {'test_2': 20, 'test_1': 10}
    

    详情class special attribute

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2021-02-09
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多