Yes!, Lets start with understanding what is a class. 

class is just a structure not the values filled in it it -  It defines how something should be laid out or structured, A class will have data members, member functions. 
So what we do to do an operation? We can give life to a class by creating an instance for it, called object. We can create any number of objects for a class.Each object can be different. object does actually carry values. 

For example: 

We have a class Example here with a member function sample which takes an argument self.

class Example(object):
    def sample(self):
        #do something

obj = Example()
^^^ So This is how we initialize an object in Python. 
obj.sample()
And we can call the member function using the object. 
       or
Example.sample(object)
An alternate option is to call the method using object.  You might be wondering why we are passing the object in here. We are using the the method’s first argument as self. The self is actually the object we passed. We dont have to pass it anyway. Python does it silently. 

 

 

Inheritance

Lets got through an example. 

class Pet(object):
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def getName(self):
        return self.name

    def getSpecies(self):
        return self.species

    def __str__(self):
        return "%s is a %s" % (self.name, self.species)
class Dog(Pet):

    def __init__(self, name, chases_cats):
        #this is known as overriding
        Pet.__init__(self, name, "Dog")
        self.chases_cats = chases_cats
        # we need to use the name and species, we must initialize the parent too. 

    def chasesCats(self):
        return self.chases_cats

class `Dog` is inherited from class `Pet’ 

The thing is, if we don’t override the __init__ method of parent class properly, that may cause some errors, may be the parents __init__ might be doing some initialisations and method invocations so we will lose it if we simply override the method but not executing the parent’s __init__ method. 
Well, Don’t break anything while inheriting :)

pet_obj = Pet(‘snoy’,’dog’)
dog_obj = Dog(‘snoy’, ‘True’) 


isinstance(pet_obj, Pet)
True
isinstance(pet_obj, Dog)
False
isinstance(dog_obj, Pet)
True
isinstance(dog_obj, Dog)
True

This shows Pet methods can be accessed by Dog instances.

The init invocation

class A(object):
    def __init__(self):
        print "A"
        super(A, self).__init__()


class B(object):
    def __init__(self):
        print "B"

class C(A,B):
    pass

C()

We have class A, B and C here. A and B are inherited to class C. What I noticed is , when it comes to multiple inheritance, the leftmost class is given the priority. The __init__ of it is invoked first, if we don’t override in the child class. The other thing I noticed is, if you want to automatically invoke class B__init__ , we have to call the super of  class A in its init. :)
 Here the class B acts as the super of class A. So we must be very careful when we do inheritance. We must know what will execute automatically, and what we have to do to execute the othe other constructors. 

OLD style and NEW style

Old style

class  OldStyle:
    pass

obj = OldStyle()
print type(obj)
print obj.__class__
print isinstance(obj, OldStyle)
print issubclass(obj.__class__, object)

<type 'instance'>
__main__.OldStyle
True
False

NewStyle

class NewStyle(object):
    pass

print type(obj)
print obj.__class__
print isinstance(obj, OldStyle)
print issubclass(obj.__class__, object)

<class '__main__.NewStyle'>
<class '__main__.NewStyle'>
True
True

The one thing we  notice here is, in old style the instance is type <type 'instance'> and the class is __main__.OldStyle, But in New style instance and class are same 
class '__main__.NewStyle'>

Public Private and Protected methods in python. 

When I did a research about this, I could find that these concepts are not really applicable in python. But we do follow these things while we code. Yeah, there are some weird scenarios to consider.  

The general concepts about these in oops is as follows, 

public:

The type or member can be accessed by any other code in the same assembly or another assembly that references it.

Private:

The type or member can only be accessed by code in the same class.

Protected:

The type or member can only be accessed by code in the same class or in a derived class.

For Example, 
class MyClass(object):
    def public_method(self):
        pass
    def __private(self):
        pass
     def _protected(self):
        pass

anywhere you can call public_method using the class instance. 
__private method, you can only call within the class.  not in inherited class, not outside of the class. 
_protected method

What I found is, the method public_method and _protected are the same - both are public.
 And in case of method __private the method name __private is not actually inherited to the attribute names of the instance. But something like _MyClass__private 
(ie, _classname__methodname) is set as attribute(in base class the __private as attribute) . So the thing is, you can’t actually call the __private using the child’s object directly. But, you can If you call the object._MyClass__private directly. Thus I understood that there are no private and protected methods in python, but  for private you can still write a __private in sub class since the base class __private methods attribute when inherited will be different (ie, _classname__methodname) . But for code readability we can follow these and write. So the other programmer can understand what’s our view toward the methods.   Weird, isn’t it ? :)

Subscribe to our newsletter. Get updates on awesome happenings in the technology world!
Newsletter subscription successfull! Something went wrong! Email is already registered!

TAGS