Welcome to the second post of this 3 part series discussing data types and objects. Well well! To be honest, trying to squeeze object-oriented programming (from now on I will use oop) to only 3 posts is a hard task because the topic is so wide but the point here is just to get you started. I will give you more links for further reading once we are done. We will start where we left off. I had asked you what changed in our post. (Link)? Well if your answer was ‘a ‘changed then you are absolutely right. Why did ‘a’ and not 20 to 20.0? This is because everything in python is an object. We have used the assignment operator ('=') to assign the variable ‘a’ to the integer 20 in the first instance so python now knows ‘a’ as an object with the id and type of the instance 20. Variables are containers for storing data values.
Id of a and id of 20 are equal meaning now python knows variable 'a' as the id and type of 20
In our diagram, we have confirmed that the ids of ‘a’ and the id 20 are equal. We can check this using the equal operator '==' which means it is ‘equivalent to’ as shown in the last expression. Also notice that we can assign other variables to 20 proving that 20 is constant and has a one to many relationships to variable-objects.Can we assign 20 to ‘a’ i.e. 20 = a? This is not possible plus a bunch of other rules as below. I recommend trying each one of them to check the output:
- A variable name must start with a letter or the underscore character
- A variable name cannot start with a number
- A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )
- Variable names are case-sensitive (age, Age, and AGE are three different variables)
1. An expression is a combination of values (or variables, operators, calls to functions - you will learn about them soon) which evaluates to a value, e.g.,
1 + 2.
2. Operators are special symbols or keywords which are able to operate on the values and perform (mathematical) operations, e.g., the
* operator multiplies two values:
x * y.
3. Arithmetic operators in Python:
/ (classic division - returns a float if one of the values is of float type),
4. Some operators act before others - the hierarchy of priorities:
/, and then the lowest priority:
5. A variable is used to represent an object within python In case the variable is assigned to another object, the value of the variable's object does not change, the variable is the one which changes and points to the new object. The previous variable is discarded and python is now only aware of the most recent assignment.
6. Objects are of two types, mutable and immutable. A mutable object can be alerted once entered but an immutable object cant.
If you have grasped what we have been talking about I think it’s time we start building our Volkswagen. But before we model that car lets come closer back home. We have a certain john in quarantine remember in our Covid 19 system so let’s model john. What is john? John is a person so we will start there. A person belongs to a certain species (human), and because humans are living things we can also have the alive and dead options as attributes. For now, let’s work on this. Below is a simplified way of how you can model such info within python using classes.
In the above diagram, we have created the class person and gave it two attributes which are the specie and the status of alive or dead.
From the above, we can confirm that classes are actually objects. To be precise, they are instances of ‘type’. Explaining this concept would lead to a talk about metaclasses and metaprogramming, advanced concepts that require a solid grasp of the fundamentals to be understood, and alas this is beyond the scope of this chapter. As usual, I mentioned it to leave a pointer for you, for when you'll be ready to dig deeper.
Next, we need to assign objects within our class. The assignment of objects is done as per our diagram below so now man is an instance of class Person. Objects inherit by default all attributes defined within its class so we should have access to both the 'specie' and the 'alive' attributes within the object 'man' as shown below:
Now that ‘Person’ and ‘man’ is defined we now need to define John who has his own unique attributes. The attributes that belong to john are age, sex, location, and name. This info is unique to John, let’s say we have another patient Mary, she will have the same attributes that belong to the class Person (alive, specie) but the age, location, and name are not constants to Person but to a specific human. So how do we model this?
When you search for an attribute in an object, if it is not found, Python keeps searching in the class that was used to create that object (and keeps searching until it's either found or the end of the inheritance chain is reached). The attributes as defined above are unique to John and are called instance attributes. These attributes are not accessible within the class as shown in the diagram below but the class attributes are accessible within man which inherits from Class Person. This concept is called attribute shadowing.
Let’s make this 3D clear. We will add another ‘alive’ attribute within man and set it to False and also add ‘age’ attribute to the Class ‘Person’ we see how python reacts to this info.
Instances get whatever is in the class, but the opposite is not true. Now that we have age within Person and we notice that Person has its own instance of age which is equal to 40 and man which is 24. These are two different attributes stored within different scopes (we will look into this in the next post) within the Class Person as far as Python is concerned. Let's delete the age within man and see what happens.
Now the attribute man inherits the age value from the class Person and output 40. Now try to delete the alive attribute within Person and try and access it within Person then within man, In the former, you should get an attribute error where the other should work fine and give False as the output. This means that assigning attributes to an instance doesn't mean that they will be found in the class. Instances get whatever is in the class, but the opposite is not true. The take away here is to be careful how you model your data because data contains the whole meaning of the system.
I hope you have noticed how we are naming variables and classes. We start with a capital letter when we are referring to classes and a small letter when we refer to variables. This is a way for doing things within Python which leads to the term ‘Pythonic’. When we say code is Pythonic it means it follows generally accepted rules within the Python community. In your interactive shell type ‘import this’ to see the ‘Zen of Python’. Your code should follow these conventions of writing code. As we strive to learn how to code we should also strive to write elegant readable code that can be easily understood and followed.
Next, we finish up our golf!