Easy Tutorial
❮ Python Func Number Randrange Python Mongodb Query Document ❯

Python3 Object-Oriented Programming

Python has been an object-oriented language since its inception. As a result, creating classes and objects is straightforward in Python. This chapter will delve into Python's object-oriented programming in detail.

If you have never been exposed to an object-oriented programming language before, you might need to understand some basic characteristics of object-oriented languages to form a fundamental concept of object-orientation, which will help you learn Python's object-oriented programming more easily.

Next, let's briefly understand some basic features of object-oriented programming.


Introduction to Object-Oriented Technology

Compared to other programming languages, Python has introduced a class mechanism with minimal new syntax and semantics.

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

Objects can contain arbitrary quantities and types of data.

Class Definition

The syntax format is as follows:

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

After instantiating a class, you can use its properties. In fact, after creating a class, you can access its properties through the class name.

Class Object

Class objects support two operations: attribute references and instantiation.

Attribute references use the standard syntax used for 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 looks like this:

Example (Python 3.0+)

#!/usr/bin/python3

class MyClass:
    """A simple class example"""
    i = 12345
    def f(self):
        return 'hello world'

# Class instantiation
x = MyClass()

# Accessing class attributes and methods
print("MyClass attribute i is:", x.i)
print("MyClass method f output is:", x.f())

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

Executing the above program outputs:

MyClass attribute i is: 12345
MyClass method f output is: hello world

A special method named __init__() (constructor) is called automatically when the class is instantiated, like this:

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

If the __init__() method is defined in the class, it will be called automatically during class instantiation. For example, instantiating the MyClass class will call the corresponding __init__() method:

x = MyClass()

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

Example (Python 3.0+)

#!/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 an Instance of the Class, Not the Class Itself

self represents an instance of the class, not the class itself. The method of a class differs from a regular function only by one special aspect—it must have an additional first parameter name, by convention named self.

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

t = Test()
t.prt()

The above example produces the following result:

&lt;__main__.Test instance at 0x100771878>
__main__.Test

It is clear from the result that self represents the instance of the class, indicating the address of the current object, while self.__class__ points to the class.

self is not a keyword in Python; replacing it with tutorialpro will still execute correctly:

class Test:
    def prt(tutorialpro):
        print(tutorialpro)
        print(tutorialpro.__class__)

t = Test()
t.prt()

The above example produces the following result:

&lt;__main__.Test instance at 0x100771878>
__main__.Test

Class Methods

Inside a class, use the def keyword to define a method, which differs from a regular function definition as it must include the parameter self, which is the first parameter and represents the instance of the class.

Example (Python 3.0+)

#!/usr/bin/python3

# Class definition
class people:
    # Define basic properties
    name = ''
    age = 0
    # Define private property, which cannot be accessed directly outside the class
    __weight = 0
    # Define constructor method
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("{} says: I am {} years old.".format(self.name, self.age))

# Instantiate the class
p = people('tutorialpro', 10, 30)
p.speak()

Executing the above program outputs:

tutorialpro says: I am 10 years old.

Inheritance

Python supports class inheritance. Without inheritance, classes would have little meaning. A derived class is defined as follows:

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

The subclass (derived class DerivedClassName) inherits attributes and methods from the parent class (base class BaseClassName).

class DerivedClassName(modname.BaseClassName):

Example (Python 3.0+)

#!/usr/bin/python3

# Class definition
class people:
    # Define basic properties
    name = ''
    age = 0
    # Define private property, which cannot be accessed directly outside the class
    __weight = 0
    # Define constructor method
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("{} says: I am {} years old.".format(self.name, self.age))

# Single inheritance example
class student(people):
    grade = ''
    def __init__(self, n, a, w, g):
        # Call the constructor of the parent class
        people.__init__(self, n, a, w)
        self.grade = g
    # Override the method of the parent class
    def speak(self):
        print("{} says: I am {} years old, and I am in grade {}.".format(self.name, self.age, self.grade))

s = student('ken', 10, 60, 3)
s.speak()

Executing the above program outputs:

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

Multiple Inheritance

Python also supports multiple inheritance to a limited extent. A class with multiple inheritance is defined as follows:

class DerivedClassName(Base1, Base2, Base3):
It is important to note the order of parent classes in parentheses. If parent classes have the same method name and it is not specified when used in the subclass, Python searches from left to right.
That is, if the method is not found in the subclass, Python checks the parent classes from left to right for the method.

## Example (Python 3.0+)

!/usr/bin/python3

Class definition

class people: # Define basic attributes name = '' age = 0 # Define private attributes, which cannot be accessed directly outside the class __weight = 0 # Define constructor 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, and I am a speaker. My topic 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() # Default to calling the method of the parent class listed first in the parentheses


Executing the above program outputs:

My name is Tim, and I am a speaker. My topic is Python.


---

## Method Overriding

If the functionality of a parent class method does not meet your needs, you can override it in the subclass. Here is an example:

## Example (Python 3.0+)

!/usr/bin/python3

class Parent: # Define parent class def myMethod(self): print ('Calling parent method')

class Child(Parent): # Define subclass def myMethod(self): print ('Calling child method')

c = Child() # Subclass instance c.myMethod() # Call overridden method super(Child, c).myMethod() # Call the overridden method of the parent class using the subclass object


The [super() function](../python/python-func-super.html) is used to call a method of the parent (superclass).

Executing the above program outputs:

Calling child method Calling parent method


**More documentation:**

[Python Subclass Inheritance of Parent Constructor](../w3cnote/python-extends-init.html)

---

## Class Attributes and Methods

### Private Class Attributes

**__private_attrs**: Starts with two underscores, declares the attribute as private, and it cannot be used or accessed directly outside the class. Within the class methods, it is used as **self.__private_attrs**.

### Class Methods

Within a class, use the `def` keyword to define a method, which is different from regular function definitions. Class methods must include the parameter `self`, which is the first parameter, representing the instance of the class.

The name `self` is not fixed; it can also be `this`, but it is best to follow the convention and use `self`.

### Private Class Methods

_privatemethod: Methods starting with two underscores are declared as private methods, which can only be called within the class and not from outside the class. self.__private_methods.

Example

Here is an example of private attributes in a class:

Example (Python 3.0+)

#!/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, instance cannot access private variable

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, instance cannot access private variable
AttributeError: 'JustCounter' object has no attribute '__secretCount'

Here is an example of private methods in a class:

Example (Python 3.0+)

#!/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('tutorialpro.org', 'www.tutorialpro.org')
x.who()        # normal output
x.foo()        # normal output
x.__foo()      # error

The above example produces the following result:

Special Methods of a Class:

Operator Overloading

Python also supports operator overloading. We can overload special methods of a class. Here is an example:

Example (Python 3.0+)

#!/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 above code produces the following output:

Vector(7,8)
❮ Python Func Number Randrange Python Mongodb Query Document ❯