Python object-oriented


Python has been an object-oriented language from the beginning. Because of this, it is easy to create classes and objects in Python. In this chapter we will introduce object-oriented programming in Python in detail.

If you have not 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 object-oriented concept in your mind, which will help you Easily learn object-oriented programming in Python.

Next, let’s briefly understand some basic characteristics of object-oriented.


Introduction to object-oriented technology

  • Class (Class): Used to describe a collection of objects with the same properties and methods. It defines the properties and methods common to every object in the collection. Objects are instances of classes.

  • Class variables: Class variables are public throughout the instantiated object. Class variables are defined in the class and outside the function body. Class variables are generally not used as instance variables.

  • Data members: Class variables or instance variables are used to process data related to the class and its instance objects.

  • Method rewriting: If the method inherited from the parent class cannot meet the needs of the subclass, it can be rewritten. This process is called method override (override ), also known as method overriding.

  • Instance variables: Variables defined in methods only act on the class of the current instance.

  • Inheritance: That is, a derived class (derived class) inherits the fields and methods of the base class (base class). Inheritance also allows an object of a derived class to be treated as a base class object. For example, there is such a design: an object of type Dog is derived from the Animal class, which simulates the "is-a" relationship (for example, Dog is an Animal).

  • Instantiation: Create an instance of a class, a specific object of the class.

  • Method: Function defined in the class.

  • Object: Instance of data structure defined by class. Objects include two data members (class variables and instance variables) and methods.


Create a class

Use the class statement to create a new class. After class is the name of the class and ends with a colon, as in the following example:

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

The help information of the class can be viewed through ClassName.__doc__.

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

Example

The following is a simple Python class example:

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

class Employee:
   '所有员工的基类'
   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, and its value will be in this class Shared between all instances. You can access it using Employee.empCount in inner class or outer class.

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


Create instance object

To create an instance of a class, you use the name of the class and accept parameters through the __init__ method.

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

Accessing properties

You can use the dot (.) to access the properties of an object. Use the name of the following class to access class variables:

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

Complete example:

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

class Employee:
   '所有员工的基类'
   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

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

The output result 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 the attributes of the class , 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 Attributes.

  • hasattr(obj,name) : Check if an attribute exists.

  • setattr(obj,name,value): Set an attribute. If the property does not exist, a new property is created.

  • delattr(obj, name) : Delete attributes.

hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age')    # 删除属性 'age'

Python built-in class attributes

  • ##__dict__: attributes of the class (contains a dictionary consisting of data attributes of the class)

  • __doc__: Class documentation string

  • __name__: Class name

  • __module__: Class definition The module in which it is located (the full name of the class is '__main__.className', if the class is located in an imported module mymod, then className.__module__ is equal to mymod)

  • __bases__: all parent classes of the class Component elements (containing a tuple composed of all parent classes)

The example of calling Python’s built-in class attributes is as follows:

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

class Employee:
   '所有员工的基类'
   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 result 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)

Like the Java language, Python uses a simple technology called reference counting to track objects in memory.

Internally, Python records how many references each object in use has.


An internal tracking variable, called a reference counter.

When an object is created, a reference count is created. When the object is no longer needed, That is, when the reference count of this object becomes 0, it is garbage collected. But recycling is not "immediate"; The interpreter will reclaim the memory space occupied by garbage objects at the 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. A circular reference occurs when two objects refer to each other, but no other variable refers to them. In this case, reference counting alone is not enough. Python's garbage collector is actually a reference counter and a cyclic garbage collector. In addition to reference counting, the garbage collector also looks at objects that have been allocated a large amount (and those that have not been destroyed by reference counting). In this case, the interpreter will pause and try to clean up any unreferenced loops.

Example

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

#!/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, "销毁"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3

Above The result of running the example is as follows:

3083401324 3083401324 3083401324
Point 销毁

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

Inheritance of the class

Object-oriented One of the main benefits that programming brings is the reuse of code, and one of the ways to achieve this reuse is through the inheritance mechanism. Inheritance can be completely understood as the type and subtype relationship between classes.

Things to note:

Inheritance syntax class Derived class name (Base class name): //... The base class name is written in brackets, and the basic class is It is specified in the tuple when the class is defined.

Some features of inheritance in python:

  • 1: In inheritance, the construction of the base class (__init__() method) will not be automatically called, it needs Call it specifically in the constructor of its derived class.

  • 2: When calling the method of the base class, you need to add the class name prefix of the base class, and you need to bring the self parameter variable. Different from calling ordinary functions in a class, you do not need to bring the self parameter

  • 3: Python always first searches for the method of the corresponding type, if it cannot find the corresponding method in the derived class method, it starts to search one by one in the base class. (First look for the calling method in this class, and then look for it in the base class if you can't find it).

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

Syntax:

Declaration of derived classes, similar to their parent classes, with a list of inherited base classes following the class name, as follows:

class SubClassName (ParentClass1[, ParentClass2, ...]):
   'Optional class documentation string'
   class_suite

Example:

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

class Parent:        # 定义父类
   parentAttr = 100
   def __init__(self):
      print "调用父类构造函数"

   def parentMethod(self):
      print '调用父类方法'

   def setAttr(self, attr):
      Parent.parentAttr = attr

   def getAttr(self):
      print "父类属性 :", Parent.parentAttr

class Child(Parent): # 定义子类
   def __init__(self):
      print "调用子类构造方法"

   def childMethod(self):
      print '调用子类方法 child method'

c = Child()          # 实例化子类
c.childMethod()      # 调用子类的方法
c.parentMethod()     # 调用父类方法
c.setAttr(200)       # 再次调用父类的方法
c.getAttr()          # 再次调用父类的方法

The execution result of the above code is as follows:

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

You can inherit multiple classes

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

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

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

You can use the issubclass() or isinstance() method to test.

  • issubclass() - Boolean function to determine whether a class is a subclass or descendant of another class. Syntax: issubclass(sub,sup)

  • isinstance(obj, Class) Boolean function returns true if obj is an instance object of the Class class or an instance object of a Class subclass.


Method rewriting

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

Example:

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

class Parent:        # 定义父类
   def myMethod(self):
      print '调用父类方法'

class Child(Parent): # 定义子类
   def myMethod(self):
      print '调用子类方法'

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

The output result of executing the above code is as follows:

调用子类方法

Basic overloading method

The following table lists some common Functions you can override in your own class:

Serial NumberMethod, Description & Simple Call
1__init__ ( self [,args...] )
Constructor
Simple calling method: obj = className(args)
2__del__( self )
Destructor method, delete an object
Simple calling method: dell obj
3__repr__( self )
Convert to a form read by the interpreter
Simple calling method: repr(obj)
4__str__( self )
is used Convert the value into a human-readable form
Simple calling method: str(obj)
5 __cmp__ (self, x)
Object comparison
Simple calling method: cmp(obj, x)

Operator overloading

Python also supports operator overloading. Examples are as follows:

#!/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 execution result of the above code is as follows:

Vector(7,8)

Class attributes Private attributes of the class with method

__private_attrs: Beginning with two underscores, it is declared that the attribute is private and cannot be used or directly accessed outside the class. When used in a method inside a class self.__private_attrs.

Methods of class

Within the class, you can use the def keyword to define a method for the class. Different from the general function definition, the class method must contain the parameter self, and it is the first parameter.

Private methods of the class

__private_method: Beginning with two underscores, it is declared that the method is a private method and cannot be called outside the class. Call self.__private_methods

Instance inside the class

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

class JustCounter:
	__secretCount = 0  # 私有变量
	publicCount = 0    # 公开变量

	def count(self):
		self.__secretCount += 1
		self.publicCount += 1
		print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.publicCount
print counter.__secretCount  # 报错,实例不能访问私有变量

Python by changing 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 instantiation Classes access private data, but you can use object._className__attrName to access attributes. Replace the last line of the above code with the following code:

.........................
print counter._JustCounter__secretCount

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

1
2
2
2