This is because of the way Python resolves names with the .. When you write self.list the Python runtime tries to resolve the list name first by looking for it in the instance object, and if it is not found there, then in the class instance.
Let's look into it step by step
self.list.append(1)
- Is there a
listname into the objectself?- Yes: Use it! Finish.
- No: Go to 2.
- Is there a
listname into the class instance of objectself?- Yes: Use it! Finish
- No: Error!
But when you bind a name things are different:
self.list = []
- Is there a
listname into the objectself?- Yes: Overwrite it!
- No: Bind it!
So, that is always an instance variable.
Your first example creates a list into the class instance, as this is the active scope at the time (no self anywhere). But your second example creates a list explicitly in the scope of self.
More interesting would be the example:
class testClass():
list = ['foo']
def __init__(self):
self.list = []
self.list.append('thing')
x = testClass()
print x.list
print testClass.list
del x.list
print x.list
That will print:
['thing']
['foo']
['foo']
The moment you delete the instance name the class name is visible through the self reference.
This is because of the way Python resolves names with the .. When you write self.list the Python runtime tries to resolve the list name first by looking for it in the instance object, and if it is not found there, then in the class instance.
Let's look into it step by step
self.list.append(1)
- Is there a
listname into the objectself?- Yes: Use it! Finish.
- No: Go to 2.
- Is there a
listname into the class instance of objectself?- Yes: Use it! Finish
- No: Error!
But when you bind a name things are different:
self.list = []
- Is there a
listname into the objectself?- Yes: Overwrite it!
- No: Bind it!
So, that is always an instance variable.
Your first example creates a list into the class instance, as this is the active scope at the time (no self anywhere). But your second example creates a list explicitly in the scope of self.
More interesting would be the example:
class testClass():
list = ['foo']
def __init__(self):
self.list = []
self.list.append('thing')
x = testClass()
print x.list
print testClass.list
del x.list
print x.list
That will print:
['thing']
['foo']
['foo']
The moment you delete the instance name the class name is visible through the self reference.
Python has interesting rules about looking up names. If you really want to bend your mind, try this code:
class testClass():
l = []
def __init__(self):
self.l = ['fred']
This will give each instance a variable called l that masks the class variable l. You will still be able to get at the class variable if you do self.__class__.l.
The way I think of it is this... Whenever you do instance.variable (even for method names, they're just variables who's values happen to be functions) it looks it up in the instance's dictionary. And if it can't find it there, it tries to look it up in the instance's class' dictionary. This is only if the variable is being 'read'. If it's being assigned to, it always creates a new entry in the instance dictionary.
Can someone explain how object/instance variables vs class/static variables work in Python?
Are all class variables in Python always defined for the first time within the __init__?
When to use class variables vs instance variables
Can someone explain "_" and "__" in python clearly for me ?
So I come from a Java background where defining, declaring and accessing static and instance level variables are pretty much a straightforward process. I want to be able to understand OOP concepts of Python properly so I have been doing some practice.
I have a class:
class A:
def init(self): pass
def someFunc(self): self.var1 += 1
I create an object of this class and call the someFunc() method:
a = A() a.someFunc()
It gives me an error. Ok, fair enough since I haven't declared a self.var1 variable yet.
Consider another example.
class A:
var1 = 10
def init(self): pass
def someFunc(self): self.var1 += 1
Now when I do this:
a = A() a.someFunc() Output: 11
I know that variables defined just below the class definition are class/static variables. And to access them you have to do A.var1
But why does it not give me an error now? I haven't created a object/instance level self.var1 variable yet, just a class level variable var1.
And when I call A.var1 the output is 10. Why is the output not the same as a.var1?
Does python automatically use the class level variable with the same name since there is no instance level variable defined with the same name? And does that in turn become a different variable from the class level variable?
Can someone please elaborate?
In Java, you declare all the variables of your class within the class but outside of any methods. You can then assign the variables accordingly within the methods of the class.
But in Python, I don't see any variables outside of methods. Most of the variables are used for the first time in the init method. That just seems a bit strange to me, but is this just how it works? You define in the init any variables you want an object of the class to have?