2008-11-21 8 views
2
class Ball: 
    a = [] 
    def __init__(self): 
    pass 

    def add(self,thing): 
    self.a.append(thing) 

    def size(self): 
    print len(self.a) 

for i in range(3): 
    foo = Ball() 
    foo.add(1) 
    foo.add(2) 
    foo.size() 

Я бы ожидать возвращения:Почему новые экземпляры класса участвуют в других экземплярах?

2 
2 
2 

Но я получаю:

2 
4 
6 

Почему это? Я обнаружил, что, выполнив a = [] в init, я могу маршрутизировать это поведение, но я не знаю, почему.

ответ

4

DOH

Я просто понял, почему.

В приведенном выше случае a - это атрибут класса, а не атрибут данных, который совместно используется всеми шарами(). Комментируя a = [] и помещая его в блок , init означает, что вместо этого это атрибут данных. (И я не мог получить к нему доступ с foo.a, чего я не должен делать.) Кажется, что атрибуты класса действуют как статические атрибуты класса, они используются всеми экземплярами.

Whoa.

Один вопрос: CodeCompletion отстой, как это. В классе foo я не могу делать сам (переменная), потому что он не определяется автоматически - он определяется функцией. Могу ли я определить переменную класса и заменить ее переменной данных?

+0

Это, вероятно, до вашего редактора ... какой редактор и платформа? – 2008-11-21 03:52:47

2

То, что вы, вероятно, хотите сделать это:

class Ball: 
    def __init__(self): 
    self.a = [] 

Если вы используете только a = [], он создает локальную переменную в функции __init__, которая исчезает, когда функция возвращает. Присвоение self.a делает его переменной экземпляра, за которой вы находитесь.

Для получения полузадачи, см., Как вы можете change the value of default parameters for future callers.

1

«Могу ли я определить переменную класса и заменить ее переменной данных?»

Нет. Это разные вещи. Переменная класса существует точно один раз - в классе.

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

Лучше попробовать другую IDE. Окончание кода кода Komodo Edit кажется разумным.

Если у вас так много переменных с такими длинными именами, что завершение кода действительно полезно, возможно, вам следует уменьшить количество классов или использовать более короткие имена. Шутки в сторону.

Я нахожу, что, когда вы добираетесь до места, где завершение кода более полезно, чем раздражает, вы превысили порог сложности «держите все в моем мозгу». Если класс не поместится в моем мозгу, это слишком сложно.