.feed-links {display:none !important;} -->

Object oriented programming in python / classes

 The object-oriented programming (OOP) allows to create entities (objects) that can be manipulated . Object-oriented programming imposes strong and clear structures. Objects can interact with each other, which greatly facilitates the understanding of the code and its maintenance. Object programming is often opposed to procedural programming , the former being more "professional" than the other because it is more reliable and cleaner.

The classes

class groups together functions and attributes that define an object. The functions of a class are also called " methods ".

Let's create a class Voiture :

# coding: utf-8

class  Car :

	def  __init__ ( self ): 
		self . name  =  "Ferrari"

Our class Voiture is like a factory for creating cars.

The __init __ () method is called when creating an object.

self.nom is a way of storing information in the classroom. We speak of a class attribute. In our case, we store the name in the attribute nom .

Objects

An object is an instance of a class . You can create as many objects as you want with a class .

Now let's create our car:

>>>  my_car  =  Car ()

Class attributes

Class attributes are used to store information at the class level. They are similar to variables.

In our example:

>>>  my_car  =  Car () 
>>>  my_car . name 
'Ferrari'

You can create an attribute for your object at any time:

>>>  my_car . model  =  "250"

And read it like this:

>>>  my_car . model 
'250'

The methods

Methods are functions defined in a class.

Let's create a new method in our car class:

# coding: utf-8

class  Car :

	def  __init__ ( self ): 
		self . name  =  "Ferrari"

	def  give_me_the_model ( self ): 
		return  "250"

Use this method:

>>>  my_car = Car () 
>>>  my_car . give_me_the_model () 
'250'

Properties

Whatever the language, for object-oriented programming it is preferable to use properties to change the values ​​of attributes. So although this is not mandatory, there is a convention of going through getter (or accessor in French) and setter ( mutator ) to change the value of an attribute. This helps to keep consistency for the programmer, if I change an attribute often it can also impact other attributes and the mutators allow this modification to be made once and for all.

An example of using properties:

# coding: utf-8

class  Car ( object ):

    def  __init__ ( self ): 
        self . _wheels = 4

    def  _get_wheels ( self ): 
        print  "Retrieve the number of wheels" 
        return  self . _wheels

    def  _set_roues ( self ,  v ): 
        print  "Changing the number of wheels" 
        self . _wheels   =   v

    wheels = property ( _get_roues ,  _set_roues )

When changing the value of the number of wheels, a message will appear. In itself this does not help but instead of doing a simple one print , you can for example send an email, etc.

Let's test our class:

>>>  my_car = Car () 
>>>  my_car . wheels = 5 
Changing  the  number  of  wheels 
>>>  my_voiture . wheels 
Retrieving  the  number  of  wheels 
5

There is another syntax going through decorators:

class  Car ( object ):

    def  __init__ ( self ): 
        self . _wheels = 4

    @property 
    def  wheels ( self ): 
        print  "Retrieve the number of wheels" 
        return  self . _wheels

    @wheels . setter 
    def  wheels ( self ,  v ): 
        print  "Changing the number of wheels" 
        self . _wheels   =   v

The result will be the same, but the reading of the code is improved.

The dir function

Sometimes it is interesting to analyze an object to fix a bug or to understand a script.

The function dir gives you an overview of the object's methods:

>>>  dir ( my_car ) 
[ '__doc__' ,  '__init__' ,  '__module__' ,  'give_me_the_model' ,  'name' ]

The special attribute __dict__

This special attribute gives you the values ​​of the attributes of the instance:

>>>  my_car . __dict__ 
{ 'name' :  'Ferrari' }

Class inheritance

Inheritance is a very useful concept. This allows you to create new classes but with an existing base.

Let's take the example of the car and create a class VoitureSport :

class  Car :

	wheels  =  4 
	motor  =  1

	def  __init__ ( self ): 
		self . name  =  "To be determined"

class  CarSport ( Car ):

	def  __init__ ( self ): 
		self . name  =  "Ferrari"

We said that VoitureSport inherited from class Voiture , so it gets all of its methods and attributes.

You can always instantiate the class Voiture if you want:

>>>  my_car = Car () 
>>>  my_car . name 
'To be determined' 
>>>  my_voiture . wheels 
4

Now let's instantiate the class VoitureSport :

>>>  my_sport_voiture = SportsCar () 
>>>  my_sport_voiture . name 
'Ferrari' 
>>>  my_sport_car . wheels 
4

We first notice that the attribute roues has been inherited. Then we notice that the method __init__ has overwritten the method of the class Voiture We then speak of method overload.

Polymorphism / method overload

As we saw above if a class inherits from another class, it inherits the methods of its parent .

Example:

# coding: utf-8

class  Car :

    wheels  =  4 
    motor  =  1

    def  __init__ ( self ): 
        self . name  =  "To be determined"
        
    def  switch on ( self ): 
        print  "The car starts"

class  CarSport ( Car ):

    def  __init__ ( self ): 
        self . name  =  "Ferrari"

my_sport_car  =  SportsCar () 
my_sport_car . turn on ()

The result:

The  car  starts

However, it is possible to override the method of the parent class by redefining it. We then speak of overloading a method .

# coding: utf-8

class  Car :

    wheels  =  4 
    motor  =  1

    def  __init__ ( self ): 
        self . name  =  "To be determined"
        
    def  switch on ( self ): 
        print  "The car starts"

class  CarSport ( Car ):

    def  __init__ ( self ): 
        self . name  =  "Ferrari"
        
    def  switch on ( self ): 
        print  "The sports car is starting"

my_sport_car  =  SportsCar () 
my_sport_car . turn on ()

The result:

The  car  of  sports  starts

Finally, last interesting point: it is possible to call the method of the parent then to make the specificity of the method. You can also call any other method.

# coding: utf-8

class  Car :

    wheels  =  4 
    motor  =  1

    def  __init__ ( self ): 
        self . name  =  "To be determined"
        
    def  switch on ( self ): 
        print  "The car starts"

class  CarSport ( Car ):

    def  __init__ ( self ): 
        self . name  =  "Ferrari"
        
    def  switch on ( self ): 
        Car . switch on ( self ) 
        print  "The sports car starts up"

my_sport_car  =  SportsCar () 
my_sport_car . turn on ()

The result:

The  car  starts 
the  car  of  sports  starts

The classes Voiture and VoitureSport therefore each have a method with the same name, but these methods do not perform the same tasks. We speak in this case of polymorphism .

Conventions

Get in the habit of naming your class only with alphanumeric characters and starting with a capital letter. And conversely the instance can be named without capital letter.

sportscar  =  sportscar ()

No comments:

Post a Comment