Переменная объекта против класса - PullRequest
3 голосов
/ 13 октября 2010

Это полностью теоретический вопрос. Предположим, следующий код:

>>> 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?

Ответы [ 4 ]

4 голосов
/ 13 октября 2010

Да, хотя c.__class__.a или type(c).a. Они немного отличаются в том, что классы старого стиля (надеюсь, все они уже мертвы - но вы никогда не знаете ...) имеют type() из <type 'instance'>__class__ работает как положено), в то время как для классы стилей type() идентичны __class__ за исключением случаев, когда объект переопределяет доступ к атрибуту.

1 голос
/ 13 октября 2010

После того, как вы присвоите ему экземпляр класса, появится атрибут класса с именем 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']. Затем проверяются суперклассы класса, но это немного усложняется.

Но, во всяком случае, главное в том, что это не обязательно должен быть один или другой. И класс, и экземпляр могут иметь разные атрибуты с одинаковыми именами, поскольку они хранятся в двух разных диктетах.

1 голос
/ 13 октября 2010

Да, вы можете получить доступ к a из объекта c, а-ля c.a.Первоначально значение было бы 10.

Однако, если вы позвоните c.f(), значение c.a будет теперь 999, , но C.a все равно будет 10. Аналогично,если вы теперь измените C.a, скажем, на 1000, c.a все равно будет 999.

По сути, когда вы создаете экземпляр экземпляра C, он будет использовать переменную класса как свою собственную a value, до , вы меняете значение a этого экземпляра, и в этом случае он больше не будет "делиться" a с классом.

1 голос
/ 13 октября 2010

Все переменные класса доступны через объекты, созданные в этом классе.

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

Атрибуты сначала ищутся в пространстве имен объекта, а затем в классе.

...