Reputation: 399
I have the class
>>> 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
I want to use one class and declare many variables. If I hope all variables have different lists. Do I do like this
class Foo:
pass
f1=Foo()
f2=oo()
f1.ls=[]
f2.ls=[]
do others
Are there some more simple and better methods. Forgive my ignorant for python class. Thanks in advance
Upvotes: 1
Views: 115
Reputation: 774
ls is a static variable as you defined. you self.ls in the init so you can have different ls in the memory.
Upvotes: 0
Reputation: 239443
When you say
class Foo:
ls=[]
ls
is defined as a class variable and all the objects which you create will will have a variable with the same name and that variable will point to the current value in the class's ls
value.
When you say
f1.ls.append(1)
You are actually mutating the original object. That's why the change is reflected in f2
as well (since they both are referring to the same object). But when you say
f2.ls = []
You are actually creating a variable on the f2
object, which refers to an empty list object. Now, the ls
object is different from f1
's ls. You can confirm this with this statement
print f1.ls is f2.ls # Will print False
print f1.ls is Foo.ls # Will print True
If you actually wanted to get a new object whenever you created an object. You have to create an instance variable, like this
class Foo:
def __init__(self):
self.ls = []
f1, f2 = Foo(), Foo()
print f1.ls is f2.ls # Will print False
Now you are binding ls
to the current instance of the class and making it point to an empty list. So, this will be different for each instance.
Upvotes: 2
Reputation: 7657
Defining a variable directly inside a class gives a class-level variable. Thus, ls
isn't unique to all instances, but is instead a property of the class Foo
. It can still be accessed, however, through its instances, which is what you did.
class Foo:
ls = []
So that:
>>> f1 = Foo()
>>> f2 = Foo()
>>> Foo.ls.append(1)
>>> Foo.ls
[1]
>>> f1.ls
[1]
>>> f2.ls
[1]
An instance level variable is unique to each instance, and can be defined in the __init__
function, as such:
class Foo:
def __init__(self):
self.ls = []
In this way, class Foo has no attribute ls
; rather, each instance constructed with __init__
does:
>>> 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
[]
Upvotes: 2
Reputation: 280227
Class-level assignments create class variables. To create instance variables, do so in the constructor:
def __init__(self):
self.ls = []
Upvotes: 3