Classes and object-oriented programming
Python supports object-oriented programming (OOP) using the built-in class keyword. Object-oriented programming allows advanced programming techniques and sustainable code that supports better software development. Because OOP is not commonly used in scripting and is above the introductory level, this book will implement OOP and some of its features in later chapters after we master the basic features of Python. What's important to keep in mind is almost everything in Python, including classes, functions, and variables, are objects. Classes are useful in a variety of situations, allowing us to design our own objects to interact with data in a custom manner.
Let's look at the datetime module for an example of how we will interact with classes and their methods. This library contains several classes, such as datetime, timedelta, and tzinfo. Each of these classes handles different functionality associated with timestamps. The most commonly used is the datetime class, which can be confusing as it is a member of the datetime module. This class is used to represent dates as Python objects. The two other mentioned classes support the datetime class by allowing dates to be added or subtracted, through the timedelta class, and time zones represented through the tzinfo class.
Focusing on the datetime.datetime class, we will look at how we can use this object to create multiple instances of dates and extract data from them. To begin, as seen in the following code block, we must import our printing statement and this library to access the datetime module's classes and methods. Next, we pass arguments to the datetime class and assign the datetime object to date_1. Our date_1 variable contains the value to represent April Fool's Day, 2018. Since we did not specify a time value when initiating the class, the value will reflect midnight, down to the millisecond. As we can see, like functions, classes too can have arguments. Additionally, a class can contain their own functions, commonly called methods. An example of a method is the call to now(), allowing us to gather the current timestamp for our local machine and store the value as date_2. These methods allow us to manipulate data that's specific to the defined instance of the class. We can see the contents of our two date objects by printing them in the interactive prompt:
>>> from __future__ import print_function
>>> import datetime
>>> date_1 = datetime.datetime(2018,04,01)
>>> date_2 = datetime.datetime.now()
>>> print(date_1, " | ", date_2)
2018-04-01 00:00:00.000 | 2018-04-01 15:56:10.012915
We can access the properties of our date objects by calling specific class attributes. These attributes are usually leveraged by code within the class to process the data, though we can also use these attributes to our advantage. For example, the hour or year attributes allow us to extract the hour or the year from our date objects. Though this may seem simple, it becomes more helpful in other modules when accessing the parsed or extracted data from the class instance:
>>> date_2.hour
15
>>> date_1.year
2018
As mentioned previously, we can always run the dir() and help() functions to provide context on what methods and attributes are available for a given object. If we run the following code, we can see that we can extract the weekday or format the date using the ISO format. These methods provide additional information about our datetime objects and allow us to take full advantage of what the class object has to offer:
>>> dir(date_1)
['__add__', '__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astime zone', 'combine', 'ctime', 'date', 'day', 'dst', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']
>>> date_1.weekday()
4
>>> date_2.isoformat()
2016-04-01T15:56:10.012915