Skip to content

Python3 Object-Oriented Programming

Python has been an object-oriented language from its inception. Because of this, creating classes and objects in Python is very easy. This chapter will introduce Python’s object-oriented programming in detail.

If you have never been exposed to object-oriented programming languages before, you may need to first understand some basic characteristics of object-oriented languages to form a fundamental concept of OOP in your mind, which will help you learn Python’s object-oriented programming more easily.

Let’s first briefly understand some basic features of object-oriented programming.


Introduction to Object-Oriented Technology

Section titled “Introduction to Object-Oriented Technology”
  • Class: Used to describe a collection of objects with the same properties and methods. It defines the properties and methods common to each object in the collection. Objects are instances of classes.
  • Method: A function defined within a class.
  • Class Variable: Class variables are common to all instantiated objects. Class variables are defined within the class but outside the function body. Class variables are typically not used as instance variables.
  • Data Member: Class variables or instance variables used to handle data related to the class and its instance objects.
  • Method Overriding: If a method inherited from a parent class cannot meet the needs of the subclass, it can be rewritten. This process is called method overriding.
  • Local Variable: A variable defined within a method that only affects the class of the current instance.
  • Instance Variable: In the declaration of a class, attributes are represented by variables. Such variables are called instance variables. An instance variable is a variable modified with self.
  • Inheritance: A derived class inherits the fields and methods of a base class. Inheritance also allows treating an object of a derived class as an object of the base class. For example, with a design where a Dog type object is derived from the Animal class, this simulates an “is-a” relationship (e.g., a Dog is an Animal).
  • Instantiation: Creating an instance of a class, a concrete object of the class.
  • Object: An instance of a data structure defined by a class. An object includes two data members (class variables and instance variables) and methods.

Compared to other programming languages, Python adds a class mechanism while minimizing the addition of new syntax and semantics.

Classes in Python provide all the basic features of object-oriented programming: the class inheritance mechanism allows multiple base classes, derived classes can override any method of the base class, and methods can call methods of the same name in the base class.

Objects can contain any number and type of data.

The syntax format is as follows:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

After a class is instantiated, its properties can be used. In fact, after creating a class, you can access its properties through the class name.

Class objects support two operations: attribute reference and instantiation.

Attribute reference uses the same standard syntax as all attribute references in Python: obj.name.

After a class object is created, all names in the class namespace are valid attribute names. So if the class definition is as follows:

#!/usr/bin/python3
 
class MyClass:
    """A simple class example"""
    i = 12345
    def f(self):
        return 'hello world'
 
# Instantiate the class
x = MyClass()
 
# Access the class's attributes and methods
print("Attribute i of MyClass is:", x.i)
print("Output of method f of MyClass is:", x.f())

The above creates a new class instance and assigns the object to the local variable x, where x is an empty object.

Executing the above program produces the following output:

Attribute i of MyClass is: 12345
Output of method f of MyClass is: hello world

Classes have a special method called __init__() (constructor method), which is automatically called when the class is instantiated, as follows:

def __init__(self):
    self.data = []

If a class defines the __init__() method, the instantiation operation of the class will automatically call the __init__() method. As shown below, instantiating the class MyClass will cause the corresponding __init__() method to be called:

x = MyClass()

Of course, the __init__() method can have parameters. Parameters are passed to the instantiation operation of the class through __init__(). For example:

#!/usr/bin/python3
 
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i)   # Output: 3.0 -4.5

self Represents the Instance of the Class, Not the Class

Section titled “self Represents the Instance of the Class, Not the Class”

There is only one special difference between class methods and ordinary functions — they must have an additional first parameter name, which by convention is called self.

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()

The execution result of the above example is:

<__main__.Test instance at 0x100771878>
__main__.Test

From the execution result, it is clear that self represents the instance of the class, representing the address of the current object, while self.class points to the class.

self is not a Python keyword. Replacing it with runoob also works normally:

class Test:
    def prt(runoob):
        print(runoob)
        print(runoob.__class__)
 
t = Test()
t.prt()

The execution result of the above example is:

<__main__.Test instance at 0x100771878>
__main__.Test

In Python, self is a conventional name used to represent the instance (object) of the class itself. It is a reference pointing to the instance, allowing methods of the class to access and manipulate the instance’s properties.

When you define a class and define methods within the class, the first parameter is typically named self. Although you can use other names, it is strongly recommended to use self to maintain code consistency and readability.

class MyClass:
    def __init__(self, value):
        self.value = value

    def display_value(self):
        print(self.value)

# Create an instance of the class
obj = MyClass(42) 

# Call the instance's method
obj.display_value() # Output 42

In the above example, self is a reference pointing to the class instance. It is used in the __init__ constructor to initialize the instance’s properties and also in the display_value method to access the instance’s properties. By using self, you can access and manipulate the instance’s properties within class methods, thereby implementing the behavior of the class.


Within a class, use the def keyword to define a method. Unlike ordinary function definitions, class methods must include the parameter self, which is the first parameter, and self represents the instance of the class.

#!/usr/bin/python3
 
# Class definition
class people:
    # Define basic attributes
    name = ''
    age = 0
    # Define private attributes; private attributes cannot be directly accessed outside the class
    __weight = 0
    # Define the constructor method
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s says: I am %d years old." %(self.name,self.age))
 
# Instantiate the class
p = people('runoob',10,30)
p.speak()

Executing the above program produces the following output:

runoob says: I am 10 years old.

Python also supports class inheritance. If a language does not support inheritance, classes have little meaning. The definition of a derived class is as follows:

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

The subclass (derived class DerivedClassName) will inherit the attributes and methods of the parent class (base class BaseClassName).

BaseClassName (the base class name in the example) must be defined in the same scope as the derived class. In addition to classes, expressions can also be used. This is very useful when the base class is defined in another module:

class DerivedClassName(modname.BaseClassName):
#!/usr/bin/python3
 
# Class definition
class people:
    # Define basic attributes
    name = ''
    age = 0
    # Define private attributes; private attributes cannot be directly accessed outside the class
    __weight = 0
    # Define the constructor method
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s says: I am %d years old." %(self.name,self.age))
 
# Single inheritance example
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        # Call the parent class constructor
        people.__init__(self,n,a,w)
        self.grade = g
    # Override the parent class method
    def speak(self):
        print("%s says: I am %d years old, and I am in grade %d"%(self.name,self.age,self.grade))
 
 
 
s = student('ken',10,60,3)
s.speak()

Executing the above program produces the following output:

ken says: I am 10 years old, and I am in grade 3

Python also supports multiple inheritance to a limited extent. The class definition of multiple inheritance is as follows:

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

Note the order of parent classes in the parentheses. If there are methods with the same name in parent classes and the subclass does not specify which one to use, Python searches from left to right. That is, when a method is not found in the subclass, it searches from left to right in the parent classes to see if they contain the method.

#!/usr/bin/python3
 
# Class definition
class people:
    # Define basic attributes
    name = ''
    age = 0
    # Define private attributes; private attributes cannot be directly accessed outside the class
    __weight = 0
    # Define the constructor method
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s says: I am %d years old." %(self.name,self.age))
 
# Single inheritance example
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        # Call the parent class constructor
        people.__init__(self,n,a,w)
        self.grade = g
    # Override the parent class method
    def speak(self):
        print("%s says: I am %d years old, and I am in grade %d"%(self.name,self.age,self.grade))
 
# Another class, preparation for multiple inheritance
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("My name is %s, I am a speaker, and the topic of my speech is %s"%(self.name,self.topic))
 
# Multiple inheritance
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,80,4,"Python")
test.speak()   # Methods have the same name; the default call is the method of the parent class that is listed first in the parentheses

Executing the above program produces the following output:

My name is Tim, I am a speaker, and the topic of my speech is Python

If the functionality of a parent class method does not meet your needs, you can override the parent class method in the subclass. The example is as follows:

#!/usr/bin/python3
 
class Parent:        # Define the parent class
   def myMethod(self):
      print ('Calling parent class method')
 
class Child(Parent): # Define the child class
   def myMethod(self):
      print ('Calling child class method')
 
c = Child()          # Child class instance
c.myMethod()         # Child class calls the overridden method
super(Child,c).myMethod() # Use the child class object to call the overridden method of the parent class

The super() function is used to call a method of the parent class (superclass).

Executing the above program produces the following output:

Calling child class method
Calling parent class method

More documentation:

Python Child Class Inheriting Parent Class Constructor Explanation


__private_attrs: Starting with two underscores, declares the attribute as private and cannot be used or directly accessed outside the class. Within the class’s internal methods, use self.__private_attrs.

Within a class, use the def keyword to define a method. Unlike ordinary function definitions, class methods must include the parameter self, which is the first parameter, and self represents the instance of the class.

The name self is not strictly required; you can also use this, but it is best to follow the convention of using self.

__private_method: Starting with two underscores, declares the method as private and can only be called within the class, not outside the class. self.__private_methods.

An example of class private attributes is as follows:

#!/usr/bin/python3
 
class JustCounter:
    __secretCount = 0  # Private variable
    publicCount = 0    # Public variable
 
    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)
 
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount)  # Error, the instance cannot access private variables

Executing the above program produces the following output:

1
2
2
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    print (counter.__secretCount)  # Error, the instance cannot access private variables
AttributeError: 'JustCounter' object has no attribute '__secretCount'

An example of class private methods is as follows:

#!/usr/bin/python3
 
class Site:
    def __init__(self, name, url):
        self.name = name       # public
        self.__url = url   # private
 
    def who(self):
        print('name  : ', self.name)
        print('url : ', self.__url)
 
    def __foo(self):          # Private method
        print('This is a private method')
 
    def foo(self):            # Public method
        print('This is a public method')
        self.__foo()
 
x = Site('Runoob Tutorial', 'www.runoob.com')
x.who()        # Normal output
x.foo()        # Normal output
x.__foo()      # Error

The execution result of the above example:

  • __init__ : Constructor, called when an object is created
  • __del__ : Destructor, used when releasing an object
  • __repr__ : Printing, conversion
  • __setitem__ : Assign by index
  • __getitem__: Get value by index
  • __len__: Get length
  • __cmp__: Comparison operation
  • __call__: Function call
  • __add__: Addition operation
  • __sub__: Subtraction operation
  • __mul__: Multiplication operation
  • __truediv__: Division operation
  • __mod__: Modulo operation
  • __pow__: Exponentiation

Python also supports operator overloading. We can overload the class’s special methods. The example is as follows:

#!/usr/bin/python3
 
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

The execution result of the above code is as follows:

Vector(7,8)