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 |