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
-
See also stackoverflow.com/questions/8701500/…Karl Knechtel– Karl Knechtel2014年01月18日 08:01:11 +00:00Commented Jan 18, 2014 at 8:01
-
possible duplicate of Static class variables in PythonBakuriu– Bakuriu2014年01月18日 08:48:17 +00:00Commented Jan 18, 2014 at 8:48
4 Answers 4
Class-level assignments create class variables. To create instance variables, do so in the constructor:
def __init__(self):
self.ls = []
Comments
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
[]
3 Comments
f2.ls = [], you aren't modifying the original class-level ls; you're redefining f2.ls and overwriting its reference to Foo.ls to refer to a new, empty list.ls from f2, you could use f2.ls[:] = []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.
2 Comments
ls is a static variable as you defined. you self.ls in the init so you can have different ls in the memory.