2014-01-18 3 views
1

У меня есть класснекоторая путаница с переменными заявленным питоном классом

>>> class Foo: 
...  ls=[] 
... 
>>> f1=Foo() 
>>> f2=Foo() 
>>> f1.ls.append(1) 
>>> f1.ls.append(2) 
>>> print f1.ls 
[1, 2] 
>>> print f2.ls 
[1, 2]    #I expect its result is empty [], why 
>>> f2.ls=[] 
>>> print f1.ls  
[1, 2] 
>>> print f2.ls 
[] 
      # If f1.ls and f2.ls refer to the same list, since i modify f2.ls, 
      # the f1.ls is empty ,too. Does the statement 'f2.ls=[]' add new attribute 
      # to f2. Where do f1.ls and f2.ls refer and how it happens 

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

class Foo: 
    pass 
f1=Foo() 
f2=oo() 
f1.ls=[] 
f2.ls=[] 
do others 

Есть ли еще более простые и лучшие методы. Простите мое невежество для класса python. Заранее спасибо

+0

См. Также http://stackoverflow.com/questions/8701500/python-class-instance-variables-and-class-variables –

+0

Возможный дубликат [Статические переменные класса в Python] (http://stackoverflow.com/ Вопросы/68645/static-class-variables-in-python) – Bakuriu

ответ

2

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

class Foo: 
    ls = [] 

Так что:

>>> f1 = Foo() 
>>> f2 = Foo() 
>>> Foo.ls.append(1) 
>>> Foo.ls 
[1] 
>>> f1.ls 
[1] 
>>> f2.ls 
[1] 

Переменная уровня экземпляра является уникальным для каждого экземпляра, и могут быть определены в функции __init__ как таковую:

class Foo: 
    def __init__(self): 
     self.ls = [] 

Таким образом, класс Foo не имеет атрибута ls; а каждый экземпляр построен с __init__ делает:

>>> f1 = Foo() 
>>> f2 = Foo() 
>>> Foo.ls.append(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: class Foo has no attribute 'ls' 
>>> f1.ls.append(1) 
>>> f1.ls 
[1] 
>>> f2.ls 
[] 
+0

Для переменной списка классов, как f1.ls, так и f2.ls относятся к Foo.ls. Если это так, когда я изменяю f2.ls = [], то почему f2.ls остается прежним значением – user2256235

+0

Говоря 'f2.ls = []', вы не изменяете исходный уровень 'ls' класса; вы переопределяете 'f2.ls' и переписываете его ссылку на' Foo.ls', чтобы ссылаться на новый пустой список. – jayelm

+0

Хорошо, спасибо, буду изучать дальше. – user2256235

3

Назначения на уровне класса создают переменные класса. Чтобы создать переменные экземпляра, сделайте это в конструкторе:

def __init__(self): 
    self.ls = [] 
2

Когда вы говорите

class Foo: 
    ls=[] 

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

Когда вы говорите

f1.ls.append(1) 

Вы фактически мутирует исходный объект. Вот почему это изменение отражается и в f2 (так как оба они ссылаются на один и тот же объект). Но когда вы говорите

f2.ls = [] 

Вы фактически создаете переменную на f2 объект, который ссылается на пустой объект списка. Теперь объект ls отличается от f1's ls. Вы можете подтвердить это с помощью этого оператора

print f1.ls is f2.ls # Will print False 
print f1.ls is Foo.ls # Will print True 

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

class Foo: 
    def __init__(self): 
     self.ls = [] 

f1, f2 = Foo(), Foo() 
print f1.ls is f2.ls # Will print False 

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

+0

спасибо за ваши комментарии. Могу ли я понимать переменные класса и переменные экземпляра типа this, переменная class любит статические переменные в C++ и переменные экземпляра, такие как обычные переменные-члены в C++. Извините мой другой вопрос, имеет ли def (function) в классе python функцию класса и функцию экземпляра – user2256235

+0

@ user2256235 Вы можете приблизительно думать о них как о статических переменных. И да Python также имеет функции класса и функции экземпляра :) Вы можете узнать больше об этом [здесь] (http://stackoverflow.com/q/38238/1903116) – thefourtheye

+0

ok спасибо. Я изучу его – user2256235

0

ls - статическая переменная, как вы определили. вы self.ls в init, чтобы вы могли иметь разные ls в памяти.

Смежные вопросы