In this post I am going to explain the syntax for Object Oriented Programming in Python. I am assuming you have already done it in other languages so if you have not done Object Oriented Programming previously you should probably look for another article about it’s principles.
At the beginning when I started learning python I found some things that I felt kind of weird, like the lack of braces and semicolons. Now that I started learning their syntax for OOP I realize that doing things weirdly is their standard. Python (kind of) allows you to implement all the principles of OOP but their syntax is not similar to the one of Java, C++, or PHP that I am familiar with. Anyway so far I don’t see any problem with their different way of doing things so I will just explain how things are done in Python.
Creating a class
This is the structure of a class in python:
1 2 3 4 5 6 7 8 9 10 11 class MyClass: some_property = 3 def method_name(self): print "I'm a method" def print_property(self): print self.some_property def with_argument(self, arg): print arg
There are few things to notice here:
- The class keyword is used to define the class
- The def keyword is used to define methods of the class
- self needs to be passed as the first argument for all methods of a class
At the begining one of the most confusing things for me was the passing of self to all of the methods. For some reason python doesn’t have a reference to the current object available to the methods by default, but it is always passed in the first argument of a method. If you forget to add self as the first argument to you method definition, your program will break when you try to call that method.
Now lets see how we can use our class:
1 2 3 4 5 6 7 >>> a = MyClass() >>> a.method_name() I'm a method >>> a.print_property() 3 >>> a.with_argument('hello') hello
As you can see from the call to with_argument, you don’t explicitly pass a reference to the current object. That, is automatically done by python. So the first argument you actually pass is the one next to self in the method definition.
An interesting thing to mention here is that by convention the reference to the current object is called self but you could call it something different if you wanted. This works exactly the same way:
1 2 3 4 5 6 7 8 class MyClass: some_property = 3 def method_name(george): print "I'm a method" def print_property(apple): print apple.some_property
1 2 3 4 class MyClass: def __init__(self): print "I'm the constructor"
The constructor is defined using the __init__ magic method. All “magic” methods in python follow the same naming convention of two underscores at the begining and two underscores at the end. Because of this distinction you shouldn’t name your own methods like this.
Let’s see it in action:
1 2 >>> a = MyClass() I'm the constructor
Lets define two classes, one called parent and one called child.
1 2 3 4 5 6 7 class parent: def my_method(self): print "I'm the parent" class child(parent): def child_method(self): print "I'm the child"
The code as it is right now would work like this:
1 2 3 4 5 >>> b = child() >>> b.my_method() I'm the parent >>> b.child_method() I'm the child
Now lets see what happens if we modify child a little.
1 2 3 4 5 6 class child(parent): def my_method(self): print "I'm the child" def child_method(self): print "I'm the child"
An lets see it at work:
1 2 3 >>> c = child() >>> c.my_method() I'm the child
As expected the child method has shadowed the parent method. What is worth mentioning is the syntax to access method from a parent.
1 2 3 4 class child(parent): def my_method(self): parent.my_method(self) print "I'm the child"
The important thing here is line 3. We are calling the my_method method of the parent class (the class, not an instance of it. That is the reason we can pass self explicitly), but the thing that does the magic is the passing of self as the first argument. Because in that context self is the instance of the current object, then you are passing the child instance to the parent class to work over it. And in action:
1 2 3 4 >> d = child() >>> d.my_method() I'm the parent I'm the child
Other important things
- In python there aren’t access modifiers. All methods are public by default, and even tought it is possible to get some kind of privacy from them it is usually not worth the trouble.
- There doesn’t exist any kind of type hinting that can be done in python to make sure that a variable passed to a method is of an specific type. This is because of the dynamic nature of python and is kind of usual for dynamic languages.
- All methods and properties can be accessed statically without having to define it.
- There is no concept of interfaces in python.
- Multiple inheritance is possible.