2012-02-22 2 views
3

Я не могу понять, что происходит здесь:Непонятные сфера поведения

class testclass: 

    def __init__(self): 
     print "new instance" 
    myList=[] 

if __name__ == "__main__": 

    inst1=testclass() 
    inst1.myList.append("wrong") 

    inst2=testclass() 
    inst2.myList.append("behaviour") 

    print "I get the",inst2.myList 

Выход:

new instance 
new instance 
I get the ['wrong', 'behaviour'] 

я ожидал бы, что список в inst1 ничего не знает о списке в inst2, но как-то это выглядит как область myList trascends создание экземпляра класса. Я нахожу это очень тревожным и озадачивающим, или я что-то упускаю здесь?

Спасибо!

ответ

6

Способ, которым вы определили myList, является атрибутом класса.

Поведение ваш ищет это один из атрибутов объекта:

class testclass: 
    def __init__(self): 
     print "new instance" 
     self.myList = [] 

Давайте попробуем:

>>> t1 = testclass() 
new instance 
>>> t2 = testclass() 
new instance 
>>> t1.myList.append(1) 
>>> t2.myList.append(2) 
>>> t1.myList 
[1] 
>>> t2.myList 
[2] 

Если вы заинтересованы в атрибутах класса, посмотрите на Class documentation. Поскольку классы в Python тоже являются объектами, например (почти) все в Python, они могут иметь свои собственные атрибуты.

3

Способ, которым вы объявили myList внутри класса, составляет класс атрибут. если вы хотели, чтобы иметь экземпляра атрибут, объявить его как это, и это будет иметь ожидаемое поведение:

class testclass: 
    def __init__(self): 
     print "new instance" 
     self.myList=[] 
1

Да, потому что это то, что класс атрибутов для. Если вам нужна переменная экземпляра, вам нужно объявить ее на самом экземпляре - обычно с помощью метода self.

1

myList инициализируются в классе времени создания экземпляра, поскольку он объявлен в теле класса, а не на объект времени создания экземпляра.

Такие свойства затем совместно используются экземплярами, пока в экземпляре не будет создана переменная с тем же именем.

Итак, в вашем случае вы используете каждый объект для доступа к тому же объекту myList (и добавьте к нему значение).

0

Если вы хотите, чтобы myList являлся переменной экземпляра, вы должны определить self.myList внутри функции init. Тогда вы должны получить поведение, которое вы ожидаете. Поскольку у вас есть это сейчас, я думаю, что myList является переменной класса и будет использоваться всеми экземплярами класса.

+1

Он будет использоваться только до назначения объекта. – Marcin

+0

Не уверен, что я понимаю ваш комментарий. Разве переменные класса не распределяются между всеми экземплярами? Если бы myList определялся как переменная класса, а как переменная экземпляра, они все равно были бы разными, а присваивания на одном не повлияли бы на другое. Я что-то упускаю? – Pierce

+0

Это моя точка. Если вы назначаете переменную экземпляра, вы больше не можете использовать этот экземпляр для доступа к переменной класса (если, возможно, вы не удалите переменную экземпляра). – Marcin