If an instance variable is not initialized in the __init__() function, can it still be referenced by a class method?
Answer
Yes, the instance variable can be referenced by a class method using self so long as it has been set before the call. If not, an AttributeError will be generated. As a general rule, it is best to initialize all of the instance variables in the __init__() function for consistency.
__init__() is what defines instance variables. Any other is a class variable until an instance changes it within its own context, thereby adopting a new instance variable.
They pyDocs have a good example of the difference between class and instance variables
ââ"
instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class:
ââ"
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
'canine'
>>> e.kind # shared by all dogs
'canine'
>>> d.name # unique to d
'Fido'
>>> e.name # unique to e
'Buddy'
So, âstore_nameâ listed in scenario #1 is the same as calling a variable inside the init method of scenario #2? If so, are there any specific cases where we might use instance variables like the one listed in scenario #1?
alternative_rocks = Store(). # Store is the class name
alternative_rocks.store_name = âAlternative Rocksâ
class Store:
def init(self, store_name):
self.store_name = store_name
We use the __init__() method so we can instantiate values particular to that instance. The variables once created are free of that method, which only runs once, ever.
An object has been created that has unique attributes. It wonât mean that other objects cannot have those values, but it does mean that now we can actually group objects by their coincidence on certain attribute values. A cool way to look at data.
Thanks @mtf. I earlier didnât understand the importance of âinitâ runs once during instantiation but now I understand.
When you said âactually group objects by their coincidence on certain attribute valuesâ, are you referring to comparing the values of instance variables of 2 different objects for the same class?
Let me know if my understanding is incorrect. Slowly trying to make my way through classes and understand it.
Precisely. Two instances of the same class will have common attributes, though their values will be distinct to each instance. We can then compare attribute values.
We wonât need to group them, though. They already are a group, and they have a name⌠The attribute.
Youâre welcome. Here is something further to considerâŚ
We have two circles. One has a radius of p and the other of q. Given that q is double what p is. by the Law of Squares we know that the area of the circle with radius q will be four times the area of the circle with radius p.
In a classified date structure with such computing ability we can readily compare any number of like objects. In geometry we call this, similarity.
How many triangles can you draw when the angles never change? How many triangles can you draw where the side lengths never change?
Answer: Infinite, and, three. Similarity sides with the first result.
It is not about math, as some would hold. We all have it within us to see the numbers and how they relate. Some math might be needed to analyze what we see, but it doesnât have to be us doing the math to see it.
If we want to understand what the math is telling us, then math it is. But, it should not keep us from seeing what it is we just saw.
This might have been asked already, but I still donât understand the difference between defining instance variables using __init__ vs directly using the object.
From a programming perspective it may prove more beneficial to have attributes defined in the class so that every instance has them in common and our program does not run the risk of raising an AttributeError because an instance does not have an expected attribute.
Is it considered a better practice to define and assign values to instance variables via the constructor as in:
class Foo:
def __init__(self, val):
self.instace_variable = val
or, âon the flyâ as is shown in the lesson with the class FakeDict and the instance variable fake_key?
My guess is the first option since it imposes structure and avoid spelling errorsâŚ
Yes the first option is normally a much better choice. On the fly makes it hard to keep track of what attributes any one instance has whereas the constructor makes it abundantly clear. Where possible stick with the first and if not try adding new attributes with method calls and such to keep it as clear as possible how each instance behaves.
class Store:
store_name = "PlaceHolder"
alternative_rocks = Store()
alternative_rocks.store_name = "Alternative Rocks"
isabelles_ices = Store()
isabelles_ices.storename = "Isabelle's Ices"
print(alternative_rocks.store_name)
# prints Alternative Rocks
print(isabelles_ices.store_name)
# prints PlaceHolder
print(isabelles_ices.storename)
# prints Isabelle's Ices
Itâs better to âdefinitively establishâ a class variable when said variable will likely exist across all instances to avoid discrepancies in variable naming.
So, my next question: once a Class is instantiated as an object are the variables only considered instance variables? Or, only if the Class variable is over-written?
Those that are declared in the constructor (__init__()) are the instance variables that are unique to that instance. Class variables are accessible to all instances and are usually limited to some value that all need in common.