Python Object-Oriented

Python has been an object-oriented language from its design inception. Because of this, it is very easy to create classes and objects in Python. In this chapter, we will introduce Python's object-oriented programming in detail.

If you haven't been exposed to object-oriented programming languages before, you may need to first understand some basic features of object-oriented languages and form a basic concept of object orientation in your mind, which will help you learn Python's object-oriented programming more easily.

Next, let's briefly understand some basic features of object orientation.


Introduction to Object-Oriented Technology

  • Class:Used to describe a collection of objects with the same attributes and methods. It defines the attributes and methods common to each object in the collection. Objects are instances of classes.
  • Class variable:Class variables are shared among all instantiated objects. Class variables are defined within the class and outside any function body. Class variables are usually not used as instance variables.
  • Data members:Class variables or instance variables, used to process data related to the class and its instance objects.
  • Method overriding:If a method inherited from the parent class cannot meet the needs of the child class, it can be rewritten. This process is called method overriding.
  • Local variables:Variables defined in methods, only affecting the class of the current instance.
  • Instance variables:In the class declaration, attributes are represented by variables. Such variables are called instance variables, declared inside the class declaration but outside the class's other member methods.
  • Inheritance:That is, a derived class inherits the fields and methods of a base class. Inheritance also allows a derived class object to be treated as a base class object. For example, there is a design: a Dog type object derives from the Animal class, which simulates an "is-a" relationship (e.g., Dog is an Animal).
  • Instantiation:Creating an instance of a class, the concrete object of the class.
  • Method:A function defined in a class.
  • Object:An instance of a data structure defined by a class. Objects include two data members (class variables and instance variables) and methods.

Creating Classes

Use the class statement to create a new class. After class comes the class name and ends with a colon:

class ClassName:
   '类的帮助信息'   #类文档字符串
   class_suite  #类体

The class's help information can be viewed via ClassName.__doc__.

class_suite consists of class members, methods, and data attributes.

Example

The following is a simple example of a Python class:

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: 'Base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary
  • The empCount variable is a class variable whose value is shared among all instances of this class. You can access it via Employee.empCount in the internal class or external class.

  • The first method, __init__(), is a special method called the class constructor or initialization method. This method is called when an instance of the class is created.

  • self represents an instance of the class. self is required when defining class methods, although the corresponding parameter does not need to be passed when calling.

self represents an instance of the class, not the class

Class methods have only one special difference from ordinary functions - they must have an additionalfirst parameter name, by convention its name is 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 0x10d066878>
__main__.Test

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

self is not a Python keyword. We can replace it with example and it will still execute normally:

Example

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

The execution result of the above example is:

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

Creating Instance Objects

When instantiating a class, other programming languages generally use the keyword new, but in Python this keyword does not exist. Class instantiation is similar to a function call.

The following uses the class name Employee to instantiate, and receives parameters through the __init__ method.

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)

Accessing Attributes

You can use the dot.to access the object's attributes. Use the class name as follows to access class variables:

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

Complete example:

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: 'Base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "Create the first object of the Employee class" emp1 = Employee("Zara", 2000) "Create the second object of the Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount

The output of executing the above code is as follows:

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2

You can add, delete, and modify class attributes as shown below:

emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8  # 修改 'age' 属性
del emp1.age  # 删除 'age' 属性

You can also use the following functions to access attributes:

  • getattr(obj, name[, default]) : Access the object's attribute.
  • hasattr(obj,name) : Check whether an attribute exists.
  • setattr(obj,name,value) : Set an attribute. If the attribute does not exist, a new attribute is created.
  • delattr(obj, name) : Delete the attribute.
hasattr(emp1, 'age') # Returns True if the 'age' attribute exists. getattr(emp1, 'age') # Returns the value of the 'age' attribute setattr(emp1, 'age', 8) # Add attribute 'age' with value 8 delattr(emp1, 'age') # Delete attribute 'age'

Python Built-in Class Attributes

  • __dict__ : The class's attributes (containing a dictionary composed of the class's data attributes)
  • __doc__ : The class's docstring
  • __name__: Class name
  • __module__: The module in which the class is defined (the class's full name is '__main__.className'; if the class is in an imported module mymod, then className.__module__ equals mymod)
  • __bases__ : The elements constituting all parent classes of the class (containing a tuple composed of all parent classes)

The following is an example of calling Python built-in class attributes:

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: 'Base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__

The output of executing the above code is as follows:

Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}

Python Object Destruction (Garbage Collection)

Python uses the simple technique of reference counting to track and reclaim garbage.

Internally, Python records how many references exist for all objects in use.

An internal tracking variable, called a reference counter.

When an object is created, a reference count is created. When this object is no longer needed, that is, when the object's reference count becomes 0, it is garbage collected. However, collection is not "immediate"; the interpreter reclaims the memory space occupied by the garbage object at an appropriate time.

a = 40      # 创建对象  <40>
b = a       # 增加引用, <40> 的计数
c = [b]     # 增加引用.  <40> 的计数

del a       # 减少引用 <40> 的计数
b = 100     # 减少引用 <40> 的计数
c[0] = -1   # 减少引用 <40> 的计数

The garbage collection mechanism not only targets objects with a reference count of 0, but can also handle circular references. Circular references refer to two objects referencing each other, but no other variables reference them. In this case, relying solely on reference counting is insufficient. Python's garbage collector is actually a reference counter and a circular garbage collector. As a supplement to reference counting, the garbage collector also keeps an eye on objects with a large total allocation (i.e., those not destroyed by reference counting). In such cases, the interpreter pauses and tries to clean up all unreferenced cycles.

Example

The destructor __del__ is called when the object is destroyed. When the object is no longer used, the __del__ method runs:

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "destroyed" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # Print the object's id del pt1 del pt2 del pt3

The running result of the above example is as follows:

3083401324 3083401324 3083401324
Point 销毁

Note:Usually you need to define a class in a separate file,

Class Inheritance

One of the main benefits of object-oriented programming is code reuse, and one way to achieve this reuse is through the inheritance mechanism.

The new class created through inheritance is called thesubclassorderived class, and the class being inherited is called thebase class、parent classorsuperclass。

Inheritance syntax

class 派生类名(基类名)
    ...

Some characteristics of inheritance in Python:

  • 1. If the parent class constructor is needed in the subclass, you must explicitly call the parent class constructor, or not override the parent class constructor. For details, see:Python subclass inheriting parent class constructor explanation。
  • 2. When calling a base class method, you need to prefix it with the base class name, and include the self parameter variable. The difference is that when calling ordinary functions within a class, you do not need to include the self parameter.
  • 3. Python always looks for the corresponding type of method first. If it cannot find the corresponding method in the derived class, it then searches in the base classes one by one. (It first looks for the called method in the current class, and only goes to the base class if it is not found.)

If more than one class is listed in the inheritance tuple, it is called "multiple inheritance".

Syntax:

The declaration of a derived class is similar to that of its parent class. The list of inherited base classes follows the class name, as shown below:

class SubClassName (ParentClass1[, ParentClass2, ...]):
    ...

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # Define parent class parentAttr = 100 def __init__(self): print "Call the parent class constructor" def parentMethod(self): print 'Call a parent class method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent class attribute:", Parent.parentAttr class Child(Parent): # Define subclass def __init__(self): print "Call the subclass constructor" def childMethod(self): print 'Call a subclass method' c = Child() # Instantiate subclass c.childMethod() # Call a method of the subclass c.parentMethod() # Call a parent class method c.setAttr(200) # Call a parent class method again - set attribute value c.getAttr() # Call a parent class method again - get attribute value

The output of the above code is as follows:

调用子类构造方法
调用子类方法
调用父类方法
父类属性 : 200

You can inherit from multiple classes

class A:        # 定义类 A
.....

class B:         # 定义类 B
.....

class C(A, B):   # 继承类 A 和 B
.....

You can use the issubclass() or isinstance() methods to check.

  • issubclass() - A boolean function that determines whether a class is a subclass or descendant of another class. Syntax: issubclass(sub, sup)
  • isinstance(obj, Class) A boolean function that returns true if obj is an instance object of the Class class or an instance object of a subclass of Class.

Method Overriding

If the functionality of your parent class method cannot meet your needs, you can override the parent class method in the subclass:

Example:

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # Define parent class def myMethod(self): print 'Call a parent class method' class Child(Parent): # Define subclass def myMethod(self): print 'Call a subclass method' c = Child() # Subclass instance c.myMethod() # Subclass calls the overridden method

After executing the above code, the output is as follows:

Calling subclass methods

Basic Overloading Methods

The following table lists some common functions that you can override in your own classes:

No.Method, Description & Simple call
1__init__ ( self [,args...] )
Constructor
Simple call method:obj = className(args)
2__del__( self )
Destructor method, delete an object
Simple call method:del obj
3__repr__( self )
Convert to a form readable by the interpreter
Simple call method:repr(obj)
4__str__( self )
Used to convert a value to a human-readable form
Simple call method:str(obj)
5__cmp__ ( self, x )
Object comparison
Simple call method:cmp(obj, x)

Operator Overloading

Python also supports operator overloading, as shown in the example below:

Example

#!/usr/bin/python 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 output of the above code is as follows:

Vector(7,8)

Class Attributes and Methods

Private Attributes of a Class

__private_attrs: Starting with two underscores declares the attribute as private, which cannot be used or directly accessed outside the class. When used within methods inside the class,self.__private_attrs。

Methods of a Class

Inside the class, use thedefkeyword to define a method for the class. Unlike ordinary function definitions, a class method must include the parameter self as the first parameter.

Private Methods of a Class

__private_method: Starting with two underscores declares the method as private and cannot be called outside the class. To call it inside the class,self.__private_methods

Example

#!/usr/bin/python # -*- coding: UTF-8 -*- 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, an instance cannot access a private variable

Python changes the name to include the class name:

1
2
2
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    print counter.__secretCount  # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'

Python does not allow class instances to access private data, but you can useobject._className__attrName( object_name._class_name__private_attribute_name) to access the attribute. Refer to the following example:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Example:
    __site = "www.example.com"

example = Example()
print example._Example__site

Execute the above code, and the result is as follows:

www.example.com

Explanation of single underscore, double underscore, and leading-trailing double underscore:

  • __foo__: Defines special methods, usually system-defined names, such as__init__()and so on.

  • _foo: A variable starting with a single underscore represents a protected type variable, that is, the protected type can only be accessed by itself and subclasses, and cannot be used forfrom module import *

  • __foo: Double underscores indicate a private type variable, which can only be accessed by the class itself.

Other extensions