This module addresses the advanced Object Oriented Programming (OOP) issues that are at the heart of Python programming.
The object-oriented approach is an evolution of good design practices that go back to the very beginning of computer programming.
This very important approach is present in most computer applications because it allows programmers to model entities representing real-life objects. Moreover, OOP allows programmers to model interactions between objects in order to solve real-life problems in an efficient, comfortable, extendable, and well-structured manner.
Imagine that the text you are now reading was rendered in a web browser created with OOP, and even the mouse cursor image is displayed using an application created with OOP. The same applies to spreadsheet handling (treat a spreadsheet as a collection of objects), and many, many other applications.
This chapter assumes that you are familiar with the basics of OOP, so to establish an understanding of common terms, we should agree on the following definitions:
Now that we’re starting to discuss more advanced OOP topics, it’s important to remember that in Python everything is an object (functions, modules, lists, etc.). In the very last section of this module, you'll see that even classes are instances.
Why is everything in Python organized as objects?
Because an object is a very useful culmination of all the terms described above:
The following issues will be addressed during this and the next module:
A class expresses an idea; it’s a blueprint or recipe for an instance. The class is something virtual, it can contain lots of different details, and there is always one class of any given type. Think of a class as a building blueprint that represents the architect’s ideas, and class instances as the actual buildings.
Classes describe attributes and functionalities together to represent an idea as accurately as possible.
You can build a class from scratch or, something that is more interesting and useful, employ inheritance to get a more specialized class based on another class.
Additionally, your classes could be used as superclasses for newly derived classes (subclasses).
Python’s class mechanism adds classes with a minimum of new syntax and semantics:
class Duck: def __init__(self, height, weight, sex): self.height = height self.weight = weight self.sex = sex def walk(self): pass def quack(self): return print('Quack')
In the code above, we have defined a class named Duck, consisting of some functionalities and attributes.
A class is a place which binds data with the code.
If you run the code, there are no visible effects. The class has been defined, but there is no code making use of it — that’s why you see no effects.
An instance is one particular physical instantiation of a class that occupies memory and has data elements. This is what 'self' refers to when we deal with class instances.
An object is everything in Python that you can operate on, like a class, instance, list, or dictionary.
The term instance is very often used interchangeably with the term object, because object refers to a particular instance of a class. It’s a bit of a simplification, because the term object is more general than instance.
The relation between instances and classes is quite simple: we have one class of a given type and an unlimited number of instances of a given class.
Each instance has its own, individual state (expressed as variables, so objects again) and shares its behavior (expressed as methods, so objects again).
To create instances, we have to instantiate the class:
duckling = Duck(height=10, weight=3.4, sex="male") drake = Duck(height=25, weight=3.7, sex="male") hen = Duck(height=20, weight=3.4, sex="female")
n the example presented above, we have created three different instances based on the Duck class: duckling, drake and hen. We haven't called any object attributes.
An attribute is a capacious term that can refer to two major kinds of class traits:
Each Python object has its own individual set of attributes. We can extend that set by adding new attributes to existing objects, change (reassign) them or control access to those attributes.
It is said that methods are the 'callable attributes' of Python objects. By 'callable' we should understand anything that can be called; such objects allow you to use round parentheses () and eventually pass some parameters, just like functions.
This is a very important fact to remember: methods are called on behalf of an object and are usually executed on object data.
Class attributes are most often addressed with 'dot' notation, i.e., <class>dot<attribute>. The other way to access attributes (variables) it to use the getattr() and setattr() functions.
In our 'duckish' example, there are the following attributes:
Examples:
If you run the code, you'll get the following example:
class Duck: def __init__(self, height, weight, sex): self.height = height self.weight = weight self.sex = sex def walk(self): pass def quack(self): return print('Quack') duckling = Duck(height=10, weight=3.4, sex="male") drake = Duck(height=25, weight=3.7, sex="male") hen = Duck(height=20, weight=3.4, sex="female") drake.quack() print(duckling.height)
Quack 10
A type is one of the most fundamental and abstract terms of Python:
Python comes with a number of built-in types, like numbers, strings, lists, etc., that are used to build more complex types. Creating a new class creates a new type of object, allowing new instances of that type to be made.
Information about an object’s class is contained in **__class__**.
If you run the code presented in the right pane, you'll get the type details of different objects.
class Duck: def __init__(self, height, weight, sex): self.height = height self.weight = weight self.sex = sex def walk(self): pass def quack(self): return print('Quack') duckling = Duck(height=10, weight=3.4, sex="male") drake = Duck(height=25, weight=3.7, sex="male") hen = Duck(height=20, weight=3.4, sex="female") print(Duck.__class__) print(duckling.__class__) print(duckling.sex.__class__) print(duckling.quack.__class__)
<class 'type'> <class '__main__.Duck'> <class 'str'> <class 'method'>
As we predicted:
Python allows for variables to be used at the instance level or the class level. Those used at the instance level are referred to as instance variables, whereas variables used at the class level are referred to as class variables.
mobile phone 01632-960004 is turned on mobile phone 01632-960012 is turned on calling 555-34343 mobile phone is turned off mobile phone is turned off
class mobil: def __init__(self, number): self.number = number def turn_on(self): print("el mòbil %s està engegat" % (self.number) ) def turn_off(self): print("el mòbil %s està apagat" % (self.number) ) def call(self,number): print("trucant al %s" % number ) m1 = mobil("111.111.111") m2 = mobil("222.222.222") m1.turn_on() m2.turn_on() m1.call("666.666.666") m1.turn_off() m2.turn_off()