Python provides Object-Orient Programming (OOP) and its simplier to learn than other interpretered languages, lukcy Python uses very similar syntax as over compiled languages so it will be easy to pickup if you used languages like Java.
At the heart of OOP is the class, which is a blue print of a data type, you use the class statement to define a class, again Python does not use curly brackets to enclose the class but indentation. To create an instance of a class you use brackets () (not the new keyword like over languages), you call it like a function.
Class and Instantiation | # Class definition class MyClass: body # Create an instance instance_of_class = MyClass() Note: By convension, classes use camel case but they don't have to |
Now that you know how to create a class lets start adding constructors, data fields (variables) and methods, however one difference with other compiled languages is that a class instance can be used as sturcture or record, data fields don't need to be declared ahead of time, the can be created on on the fly . The pass statement in Python is used when a statement is required syntactically but you do not want any command or code to execute. The pass statement is a null operation; nothing happens when it executes.
Class and Instantiation | # Class definition class MyClass: pass # pass does nothing, its a place holder # Create an instance instance_of_class = MyClass() # Notice we did not declare a variable var1 in the class above, we can add these on the fly instance_of_class.var1 = 5 print(instance_of_class.var1) |
Python has a concept of a constructor in other languages, you can initialize fields automatically by using a __init__ initialize method in the body of a class, it is run everyting you create a new instance. You can pass variables to the __init__ method as well.
Instance Variables | # Class definition class MyClass: def __init__(self, name="Will"): # we can also pass values, self is always first argument self.var1 = 5 self.name = name # we pass name which is assigned # Create an instance instance_of_class = MyClass("Paul") # pass value to variable name print(str(instance_of_class.var1) + " " + instance_of_class.name) Note: self refers to the instance that was created, its very similar to this() in Java |
Default values | # Class definition class MyClass: def __init__(self, name="Will"): # use a dfault value if none is passed self.name = name # we pass name which is assigned # Create an instance instance_of_class = MyClass() # name will be set to default value as we have not passed one print(instance_of_class.name) Note: default values are useful to make sure variables are set to something |
You can create the classes own method, which generally should work on the data of that class (instance), again we pass self as the first argument
Instance Variables | # Class definition class MyClass: def __init__(self, name): # we can also pass values self.var1 = 5 self.name = name # we pass name which is assigned def getname(self): # we use self to reference the instance variables return self.name # we use self to get the name variable # Create an instance instance_of_class = MyClass("Paul") print(str(instance_of_class.var1) + " " + instance_of_class.getname()) |
You can create class variables which can be used by all methods of that class
Class Variables | # Class definition class MyClass: lname = "Valle" # class variable, also acts like a static class variable def __init__(self, fname): # we can also pass values self.fname = fname # we pass name which is assigned def getname(self): return self.fname + " " + self.lname # Create an instance instance_of_class = MyClass("Paul") print(instance_of_class.getname()) print(MyClass.lname) # class variables are like static class variables |
You can also create static and class methods by using the @staticmethod and @classmethod decorators, with having to initialize the class
Static and Class Methods | # Class definition class MyClass: lname = "Valle" # class variable @staticmethod # static method def getfullname(fname): return fname + " " + MyClass.lname # accessing the class variable @classmethod # class method def getlname(cls): return MyClass.lname # accessing the class variable # Notice we don't initialize anything print(MyClass.getfullname("Paul")) # use the static method print(MyClass.getlname()) # use the class method |
Python does not restrict too much when it comes to inheritance because of it dynamic nature, you can abstract variables and methods, etc in a class then inherit that class. The superclass looks like a normal class but the subclass needs to call the superclasses __init__ method and passing any parameters, it does this but calling super.__init__()
Python does not restrict you in regards to multiple inhertiance but making code too complex helps no one, so keep things simple and most of all readable.
Inheritance example | # Superclass definition class Person: def __init__(self, fname, lname): self.fname = fname # variable will get inherited by subclasses self.lname = lname # variable will get inherited by subclasses def getfullname(self): # method will get inherited by subclasses return self.fname + " " + self.lname # Subclass definition class Professor(Person): # inherit Person class def __init__(self, fname, lname): super().__init__(fname, lname) # call superclasses __init__ method # Subclass definition class Student(Person): # inherit Person class def __init__(self, fname, lname): super().__init__(fname, lname) # call superclasses __init__ method professor1 = Professor("Will", "Hay") # create professor instance student1 = Student("Paul", "Valle") # create student instance print("Professor: " + professor1.getfullname()) # get professors name, using inherited method print("Student: " + student1.getfullname()) # get students name, using inherited method |
Python also provides encapsulation were you can make variables and methods private, they are used to enchance security and reliability by protecting important and delicate parts of the object. You use the double underscore (__) to declare something private
Private variable and method example | # Class definition class MyClass: __var1 = "class var1" # private class variable def __init__(self): # we can also pass values self.__var2 = "class var2" def __getname(self): # private class method return self.__var1 + ", " + self.__var2 def getname(self): # you have to get name via this method only return self.__getname() # Create an instance instance1 = MyClass() print(instance1.getname()) # print(instance1.__getname()) # compile error __getname() is private # print(MyClass.__var1) # compile error __var1 is private |
You can use the @property decorator to allow you to setup setter/getter methods and this use the dot notation to make your code cleaner
Private variable and method example | # Class definition class Employee: def __init__(self, name): # we can also pass values self.__name = name @property def name(self): # property (you can create getter/setter) return self.__name @name.setter # setter def name(self, value): self.__name = value @name.getter # getter def name(self): return self.__name # Create an instance emp1 = Employee("Paul Valle") print(emp1.name) # use dot notation to access name emp1.name = "Will Hay" print(emp1.name) # use dot notation to access name |