I am new in python i read about Instance variable:
A variable that is defined inside a method and belongs only to the
current instance of a class.
So i test it:
Consider this code:
class test:
count=0
def __init__(self):
test.count += 1
I have a class that add count after Instantiation.
I run this:
t1=test()
t1.count=100
and then I create new instance:
t2=test()
t2.count # 2
then create another instance:
t3=test()
t3.count # 3
t2.count # 3
and then :
t1.count # I get 100
My question is why t2 and t3 was update but if change value of instance variable of specific instance the instance 's instance variable was not update?
In t2 and t3, since you haven't defined an instance variable count, referring to, e.g., t2.count looks up the name in the class scope and evaluates to the class variable test.count.
In t1, you've created a completely different instance variable count that just happens to have the same name as the class variable. t1.count therefore returns this instance variable.
Because instance attributes shadow class attributes, but they are independent.
When you try to access t2.count, there is no instance attribute (t2.__dict__ does not have a count key), so Python next looks at type(t2) to see if it can find the attribute there. The class does have such an attribute, so test.count is returned.
t1.count on the other hand finds the instance attribute and returns that. test.count is never considered.
Related
I run the following very trivial Python code. I am very surprised that it actually run. Could someone explain to me why I can even assign values to "nd" and "hel" without defining them in the class definition? Is this because the attribute can be added in the instance level?
class tempClass(object):
a = tempClass()
a.nd = 1
a.hel = 'wem3'
Python has no notion of variable declaration, only assignments. The same applies to attributes: you simply assign an initial value to bring it into existence.
There is nothing special about the __init__ method in this regard. For example,
class TempClass(object):
def __init__(self):
self.nd = 1
a = tempClass()
a.hel = 'wem3'
Both attributes are created in the same way: by assigning a value to them. __init__ is called when a is first created, but otherwise is not special. self inside __init__ is a reference to the object referenced by a, so self.nd = 1 is identical to a.nd = 1. After the object is created, a.hel is created and initialized with 'wem3' by the same process.
class Foo:
bar = 1
......etc.
I know when creation a instance, bar is created before __init__,
I want to know if it is the very first thing to create the bar property when creating
a instance for Foo.
Also, does the bar already exists in memory before any instance is created?
Remember that in Python class is an executable statement (as too are def and import). So the answer to your question is that bar is created when the class statement executes.
Specifically, when a class statement executes, the body of the class is executed in a namespace that is usually just a dict. When the body has finished executing a class object is created with a copy of the resulting dict as the __dict__ attribute for the class.
The dict at this point contains all the names bound inside the class body bar=1 for example, but also any functions that were defined in the class body.
Instances, when they are created, don't get a copy of bar, they just refer back to the class. When you lookup a name on an instance Python looks in both the instance's __dict__ and the class's __dict__.
Those properties are stored in the the __dict__ of the class itself. They never exist on the instance (or rather the instance's __dict__) unless you assign it manually.
For example, if you use self.bar += 1 in a method you'll read the 1 from the class-level variable and assign 2 to the instance-level variable. The next time you run this statement, bar exists on the instance level so you read that 2 and replace it with 3.
State variables will be assigned before the constructor (init). So...
Class Foo:
bar = 1
def __init__(self):
bartwo = 2
would see bar take on a value of 1, before bartwo was assigned, though. My guess is your question is "If I assign a state variable before a constructor, can I use it in the constructor. Yes.
I was wondering what was the difference between the Foo.var= user input and self.var= userinput in the 2 classes.
class foo():
var=None
def __init__(self,userinput):
foo.var=userinput
class bar():
var=None
def __init__(self,userinput):
self.var=userinput
foo refers to the class, self refers to the object.
Class members are a property of the class (and thus are shared between all objects of that class), while instance members are a property of the specific object, so a change to an instance member affects only the given object.
When you operate on an object, the members it has are a merge of the class members and the instance members. When two members with the same name are defined, the instance members have the priority.
Thus:
bar sets an instance variable; that change has effect only on the current instance, so if you do:
b=bar(10)
c=bar(20)
you'll see that c.var is 20 and b.var is 10; nothing strange here;
foo sets a class variable, which is common to all the instances; so, if you do:
f=foo(10)
g=foo(20)
you'll see that both f.var and g.var will be 20, because they both actually refer to foo.var, that was last set to 20 in g's constructor;
on the other hand, instance variables shadow class variables; so, if you do
f=foo(10)
g=foo(20)
f.var=30
you'll have g.var==foo.var==20, but f.var==30, since now f.var refers to the instance variable f.var; but, if you do
del f.var
now the instance (f's) attribute var no longer exists, and thus f.var refers again to the class attribute var (thus f.var==g.var==foo.var==20).
Long story short: normally you'll want to use self.var (i.e. instance members); classname.var is only for sharing stuff between all instances of a given class.
I'd like to point to an existing post which explains the difference perfectly in my opinion.
Python: Difference between class and instance attributes
Yes,
In the first instance you are setting the variable for all instances of foo this is because it is a class variable.
In the second case you are only setting the variable for that instance of foo.
For Example:
class pie():
def __init__(self, j):
pie.var = "pies" + str(j)
print (self.var)
def __str__(self):
return self.var
a = pie(1)
b = pie(2)
print (a)
print (b)
I created the following example to understand the instances in python
import time;
class test:
mytime = time.time();
def __init__(self):
#self.mytime = time.time();
time.sleep(1);
pass
from test import test
test1 = test()
test2 = test()
print test1.mytime
print test2.mytime
test1.mytime = 12
print test1.mytime
print test2.mytime
in this case the output id the following:
1347876794.72
1347876794.72
12
1347876794.72
I expected that the test2.mytime is bigger with 1 second than the test1.mytime. Why doesn't created a copy about the mytime in each instance?
Let's look at those lines:
class test:
mytime = time.time();
Here you set class member value, which is calculated once when class definition is executed, so time.time() is calculated once when module that contains class test is loaded.
Every instance of the class test will receive that precalculated value and you must override that value (e.g. in __init__ method), accessing it via self (which is a special argument that stores reference to an instance), thus setting instance member value.
the mytime = time.time() is executed when the class is defined(when the interpreter runs the class-definition-code, and this will be run only once, so all instances will get the same mytime.
if you want different mytime in different instances, you have to use the self's one, and access it with instance name rather than class name.
The reason the value never changes is because it is a class variable meaning when the class is defined and evaluated but not when instances are made then the value is set.
If you want the value to change make it set inside the initialiser
The mytime variable is first created as a class variable and not an instance variable.
Python tries to locate a name on an instance first and if it is not found it will lookup the name on the class. You can query the namespace of any object (including) classes by looking at the object's __dict__, which is a dictionary containing the instance variables.
As soon as you set test1.mytime = 12, you created a new name in that object's __dict__, which from then on shadowed the class variable with the same name.
let's uncomment "self.mytime = time.time()" line from your code:
class test:
mytime = time.time();
def __init__(self):
self.newtime = time.time();
time.sleep(1);
#pass - no use of pass here
test1 = test()
test2 = test()
print test1.mytime
o/p: 1347883057.638443
print test2.mytime
o/p: 1347883057.638443
In this case, "mytime" variable is like static class member. and all instances of test() class (i.e: test1 and test2) will share same value of class attributes.
print test1.newtime
o/p: 1347883063.421356
print test2.newtime
o/p: 1347883068.7103591
whereas, value of instance variable. will be different for each instance of class.
therefore, to get different timing for each instance. you need to declare instance variable using "self" in "init" method.
self = instance as a first parameter in class method
init = default constructor method in python for defined class
Hope, it will help.
I tried this example code:
class testclass:
classvar = 'its classvariable LITERAL'
def __init__(self,x,y):
self.z = x
self.classvar = 'its initvariable LITERAL'
self.test()
def test(self):
print('class var',testclass.classvar)
print('instance var',self.classvar)
if __name__ == '__main__':
x = testclass(2,3)
I need some clarification. In both cases, I'm able to access the class attribute and instance in the test method.
So, suppose if I have to define a literal that needs to be used across all function, which would be the better way to define it: an instance attribute or a class attribute?
I found this in an old presentation made by Guido van Rossum in 1999 ( http://legacy.python.org/doc/essays/ppt/acm-ws/sld001.htm ) and I think it explains the topic beautifully:
Instance variable rules
On use via instance (self.x), search order:
(1) instance, (2) class, (3) base classes
this also works for method lookup
On assigment via instance (self.x = ...):
always makes an instance variable
Class variables "default" for instance variables
But...!
mutable class variable: one copy shared by all
mutable instance variable: each instance its own
Class variables are quite good for "constants" used by all the instances (that's all methods are technically). You could use module globals, but using a class variable makes it more clearly associated with the class.
There are often uses for class variables that you actually change, too, but it's usually best to stay away from them for the same reason you stay away from having different parts of your program communicate by altering global variables.
Instance variables are for data that is actually part of the instance. They could be different for each particular instance, and they often change over the lifetime of a single particular instance. It's best to use instance variables for data that is conceptually part of an instance, even if in your program you happen to only have one instance, or you have a few instances that in practice always have the same value.
It's good practice to only use class attributes if they are going to remain fixed, and one great thing about them is that they can be accessed outside of an instance:
class MyClass():
var1 = 1
def __init__(self):
self.var2 = 2
MyClass.var1 # 1 (you can reference var1 without instantiating)
MyClass.var2 # AttributeError: class MyClass has no attribute 'var2'
If MyClass.var is defined, it should be the same in every instance of MyClass, otherwise you get the following behaviour which is considered confusing.
a = MyClass()
b = MyClass()
a.var1, a.var2 # (1,2)
a.var1, a.var2 = (3,4) # you can change these variables
a.var1, a.var2 # (3,4)
b.var1, b.var2 # (1,2) # but they don't change in b
MyClass.var1 # 1 nor in MyClass
You should define it as a class attribute if you want it to be shared among all instances. You should define it as an instance variable if you want a separate one for each instance (e.g., if different instances might have different values for the variable).