【问题标题】:Object vs. class variable对象与类变量
【发布时间】:2010-10-12 20:30:44
【问题描述】:

这是一个完全理论的问题。假设如下代码:

>>> class C:
...     a = 10
...     def f(self): self.a = 999
...
>>>
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999

此时,类变量C.a是否仍可通过对象c访问?

【问题讨论】:

  • 你试过了,它奏效了。这不是理论上的。这甚至不是一个真正的问题。有效。你还想知道什么?
  • 我想知道什么? “此时,类变量 C.a 是否仍可通过对象 c 访问?”

标签: python syntax theory


【解决方案1】:

是的,尽管c.__class__.atype(c).a。两者在旧式课程中略有不同(希望这些课程现在都死了 - 但你永远不知道......)有一个 type()<type 'instance'> (和 __class__ 按预期工作)而对于新 -样式类,type()__class__ 相同,除非对象覆盖属性访问。

【讨论】:

    【解决方案2】:

    所有类变量都可以通过从该类实例化的对象访问。

    >>> class C:
    ...     a = 10
    ...     def f(self): self.a = 999
    ... 
    >>> C.a
    10
    >>> c = C()
    >>> c.a
    10
    >>> c.f()
    >>> c.a
    999
    >>> c.__class__.a
    10
    >>> c.a
    999
    >>> del(c.a) 
    >>> c.a
    10
    

    属性首先在对象命名空间中搜索,然后是类。

    【讨论】:

      【解决方案3】:

      是的,您可以从对象c 访问a,也就是c.a。该值最初为 10。

      但是,如果您调用c.f()c.a 的值现在将为 999,C.a 仍将是 10。同样,如果您现在将 C.a 更改为,比如,1000,c.a 仍然是 999。

      基本上,当您实例化C 的实例时,它将使用类变量作为自己的a 值,直到您更改该实例的a 的值,其中如果它不再与班级“共享”a

      【讨论】:

        【解决方案4】:

        在类实例上分配给它之后,有一个名为a 的类属性和一个名为a 的实例属性。我举例说明:

        >>> class Foo(object):
        ...     a = 10
        ... 
        >>> c = Foo()
        >>> c.a
        10
        >>> c.a = 100  # this doesn't have to be done in a method
        >>> c.a   # a is now an instance attribute
        100
        >>> Foo.a  # that is shadowing the class attribute
        10
        >>> del c.a  # get rid of the instance attribute
        >>> c.a     # and you can see the class attribute again
        10
        >>> 
        

        区别在于一个作为条目存在于Foo.__dict__ 中,另一个作为条目存在于c.__dict__ 中。当您访问instance.attribute 时,如果存在instance.__dict__['attribute'],则返回它,如果不存在则检查type(instance).__dict__['attribute']。然后检查该类的超类,但这会稍微复杂一些。

        但无论如何,主要的一点是它不必是其中之一。类和实例都可以具有相同名称的不同属性,因为它们存储在两个单独的字典中。

        【讨论】:

        • 这是最清楚的解释。谢谢你的好答案。
        猜你喜欢
        • 1970-01-01
        • 2014-05-07
        • 2010-11-25
        • 2013-03-12
        • 2012-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多