Что происходит, когда я создаю экземпляр класса в Python? - PullRequest
3 голосов
/ 05 мая 2010

Не могли бы вы прояснить некоторые идеи, стоящие за классами и экземплярами классов Python?

Учтите это:

class A():
    name = 'A'

a = A()

a.name = 'B' # point 1 (instance of class A is used here)

print a.name
print A.name

печать:

B
A

если вместо этого в point 1 я использую имя класса, вывод будет другим:

A.name = 'B' # point 1 (updated, class A itself is used here)

печать:

B
B

Даже если бы классы в Python были своего рода прототипом для экземпляров классов, я бы ожидал, что уже созданные экземпляры останутся нетронутыми, то есть вы получите следующий вывод:

A
B

Можете ли вы объяснить, что на самом деле происходит?

Ответы [ 3 ]

4 голосов
/ 05 мая 2010

Прежде всего, правильный путь в Python для создания полей экземпляра (а не полей класса) использует метод __init__.Я верю, что вы уже это знаете.

Python не ограничивает вас в присвоении значений необъявленным полям объекта.Например, рассмотрим следующий код:

class Empty: pass
e = Empty()
e.f = 5
print e.f # shows 5

Итак, что происходит в вашем коде:

  1. Вы создаете класс A со статическим полем name, которому присвоеноA.
  2. Вы создаете экземпляр A, a.
  3. Вы создаете новое поле для объекта a (но не для других экземпляров A) и присвойте ему B
  4. Вы печатаете значение a.name, уникальное для объекта a.
  5. Вы печатаете значение статического поля A.name, который относится к классу
1 голос
/ 05 мая 2010

Возможно, этот пример может помочь разобраться. Напомним, что имена Python - это не хранилище (как переменные в других языках), а ссылки на хранилище. Вы можете найти то, к чему относится имя с помощью id (name). Идентификационный оператор x is y сообщает, указывают ли два имени на один и тот же объект.

>>> class A(object):
...     name = 'A'
... 
>>> x = A()
>>> A.name is x.name
True
>>> x.name = 'fred'  # x.name was bound to a new object (A.name wasn't)
>>> A.name is x.name
False
>>> x = A()          # start over
>>> A.name is x.name
True                 # so far so good
>>> A.name = 'fred'
>>> A.name is x.name 
True                 # this is somewhat counter-intuitive
1 голос
/ 05 мая 2010

Вы также должны посмотреть на эти темы SO для дальнейших объяснений:
Статические переменные класса в Python
Как в Python получить доступ к "статическим" переменным класса внутри методов класса

И официальный учебник: http://docs.python.org/tutorial/classes.html#SECTION0011320000000000000000

Имейте в виду, что оператор присваивания "=" в python ведет себя иначе, чем C ++ или Java:
http://docs.python.org/reference/simple_stmts.html#assignment-statements

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...