Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Python object-oriented


May 10, 2021 Python2


Table of contents


Python object-oriented

Python has been an object-oriented language since its inception, which is why it is easy to create a class and object in Python. I n this section we'll cover Python's object-oriented programming in more detail.

If you haven't been exposed to object-oriented programming languages before, you might want to understand some of the basic characteristics of object-oriented languages and develop a basic object-oriented concept in your head that will make it easier for you to learn Python's object-oriented programming.

Let's start with a simple look at some of the basic features of object-oriented.


Introduction to object-oriented technologies

  • Class: A collection of objects that describe objects that have the same properties and methods. I t defines the properties and methods that are common to each object in the collection. An object is an instance of a class.
  • Class variables: Class variables are common throughout the instantiated object. C lass variables are defined in the class and outside the function body. Class variables are not typically used as instance variables.
  • Data members: Class variables or instance variables are used to process related data for classes and their instance objects.
  • Method overloading: If the method inherited from the parent class does not meet the needs of the child class, it can be overridden, a process called override, also known as method overloading.
  • Instance variable: A class that defines a variable in a method that only affects the current instance.
  • Inheritance: That is, a derived class inherits the fields and methods of the base class. I nheritance also allows the object of a derived class to be treated as a base class object. For example, there is a design where a Dog-type object is derived from an Animal class, which simulates an "is-a" relationship (example: Dog is an Animal).
  • Instantiation: Creates an instance of a class, the specific object of the class.
  • Method: A function defined in a class.
  • Object: An instance of a data structure defined by a class. The object consists of two data members (class and instance variables) and methods.

Create a class

Use the class statement to create a new class, followed by the name of the class and ending with a colon, as follows:

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

The help information for the class can be ClassName.__doc__ the .

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

Instance

Here's a simple example of a Python class:

#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 whose value is shared among all instances of the class. You can use Employee.empCount access in internal or external classes.
  • The first method, __init__() method, is a special method called a constructor or initialization method of a class, which is called when an instance of that class is created
  • Self represents an instance of a class, and self is required to define the method of the class, although the appropriate parameters do not have to be passed in at the time of the call.

Self represents an instance of a class, not a class

The methods of a class have only one special difference from normal functions -- they must have an additional first argument name, which by convention is self.

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

The above examples perform as follows:

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

It is clear from the execution results that self represents an instance of the class, representing the address of the current object, while self.class points to the class.

Self is not a Python keyword, and it works if we replace him with w3cschool:

Instance:

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

The above examples perform as follows:

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

Create an instance object

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

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

Access the property

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

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

Full example:

#coding=utf-8
#!/usr/bin/python

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 above code output results are as follows:

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

You can add, remove, and modify the properties of the class as follows:

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

You can also access properties using the following functions:

  • getattr (obj, name, default): Access the properties of the object.
  • Hasattr (obj, name): Check for the existence of a property.
  • setattr (obj, name, value): Set a property. If the property does not exist, a new property is created.
  • delattr (obj, name): Delete the property.
hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age')    # 删除属性 'age'

Python has built-in class properties

  • __dict__: The property of the class (contains a dictionary consisting of the data properties of the class)
  • __doc__: The document string of the class
  • __name__: Class name
  • __module__: The module in which the class is defined (the full name of the class is '__main__.className', and if the class is in an import module mymod, className.__module__ equals mymod)
  • __bases__: All parent composition elements of the class (including groups consisting of all parent classes)

The instance of Python's built-in class property call is as follows:

#coding=utf-8
#!/usr/bin/python

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 above code output results are 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 the simple technique of reference counting to track objects in memory.

Inside Python records how many references each object in use has.

An internal trace variable, called a reference counter.

When an object is created, a reference count is created, and when the object is no longer needed, that is, when the object's reference count becomes 0, it is garbage collected. However, recycling is not "immediate" and the memory space occupied by the garbage object is reclaimed by the interpreter 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 also handles the case of circular references. L oop references refer to two objects that reference each other, but no other variables refer to them. I n this case, it is not enough to use a reference count alone. P ython's garbage collector is actually a reference counter and a recycling garbage collector. T o complement the reference count, the garbage collector also pays attention to objects that are allocated a large total (and those that are not destroyed by the reference count). I n this case, the interpreter pauses in an attempt to clean up all unresoled loops.

Instance

The destructor __del__, __del__ called when the object is gone, and when the object is no longer in use, __del__ method runs:

#coding=utf-8
#!/usr/bin/python

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) # 打印对象的id
del pt1
del pt2
del pt3

The above examples run as follows:

3083401324 3083401324 3083401324
Point destroyed

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

The inheritance of the class

One of the main benefits of object-oriented programming is the reuse of code, and one way to achieve this reuse is through inheritance mechanisms. Inheritance is perfectly understandable as a type and sub-type relationship between classes.

Places to note: Inheritance syntax class derived class name (base class name)/... In the parentheses of the base class name writing, the base class is specified in the metagroup when the class is defined.

Some of the characteristics inherited in Python:

  • 1: The construction (__init__() method of the base class is not automatically called in inheritance, it needs to be called specifically in the construct of its derived class.
  • 2: When calling the method of the base class, you need to prefix the class name of the base class, and you need to bring the self parameter variable. The difference is that you don't need to take self parameters with you when you call a normal function in a class
  • 3: Python always looks for the method of the corresponding type first, and if it can't find the corresponding method in the derived class, it starts looking one by one in the base class. (Find the called method in this class first, and you can't find it before you go to the base class).

If more than one class is listed in the inheritance group, it is called multi-inheritance.

Grammar:

Declarations of derived classes, similar to their parent classes, inherit a list of base classes that follow the class name, as follows:

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

Instance:

#coding=utf-8
#!/usr/bin/python

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 above code executes as follows:

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

You can inherit more than one class

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

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

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

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

  • issubclass() - Boolean function determines that one class is a subclass or descendant class of another class, syntax: issubclass (sub, sup)
  • The isinstance (obj, class) Boolean function returns true if the obj is an instance object of the Class class or an instance object of a class subclass.

Method override

If the functionality of your parent class method does not meet your needs, you can override your parent's method in the child class:

Instance:

#coding=utf-8
#!/usr/bin/python

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

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

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

The above code output results are as follows:

调用子类方法

The underlying overload method

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

Serial number Method, which describes a simple call
1 __init__ ( self [,args...] )
The constructor
Simple call method: obj s className (args).
2 __del__( self )
Destruct method, remove an object
Simple call method: dell obj
3 __repr__( self )
Converted into a form for the interpreter to read
Simple call method: repr (obj).
4 __str__( self )
Used to convert values into forms that are suitable for human reading
Simple call method: str (obj).
5 __cmp__ ( self, x )
Object comparison
Simple call method: cmp (obj, x).

The operator is overloaded

Python also supports operator overloading, 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 above code execution results are as follows:

Vector(7,8)

Class properties and methods

The private property of the class

__private_attrs: Two underscores begin with a declaration that the property is private and cannot be used or accessed directly outside the class. When used in methods inside a class self.__private_attrs.

The method of the class

Inside the class, the def keyword can be used to define a method for the class, which, unlike a general function definition, must contain the argument self and be the first argument

The private method of the class

__private_method: Two underlined beginnings that declare the method private and cannot be called outside the class. Call the system inside the self.__private_methods

Instance

#coding=utf-8
#!/usr/bin/python

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 includes class names by changing the 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 instantiated classes to access private data, but you can use object._className__attrName to access properties and replace the last line of code with the following code:

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

The above code is executed as follows:

1
2
2
2

Single underscore, double underscore, head and tail double underscore description:

  • __foo__: Defines a special method, typically a system-defined name, such as __init__ () and so on.
  • _foo: A variable of the protected type, which begins with a single underscore, means that the protection type can only be accessed by itself and sub-classes, and cannot be used for from from import module .
  • __foo: Double underscore represents a private type variable that can only be accessed by the class itself.