亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Python

Python - 面向对象

上一页下一页

Python 从出现以来一直是一种面向对象的语言。因此,创建和使用类和对象非常容易。本章帮助你成为使用 Python 面向对象编程支持的专家。

如果您以前没有任何面向对象 (OO) 编程的经验,您可能需要查阅有关它的入门课程或至少某种教程,以便掌握基本概念。

不过,这里是面向对象编程 (OOP) 的小介绍,让您快速上手 -

OOP 术语概述

创建类

语句创建一个新的类定义。类名紧跟关键字class 后跟一个冒号如下 -

class ClassName:
   'Optional class documentation string'
   class_suite

示例

以下是一个简单的 Python 类的示例 -

class Employee:
   'Common 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

创建实例对象

要创建类的实例,您可以使用类名调用该类并传入其 __init__ 的任何参数 方法接受。

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)

访问属性

您可以使用带有对象的点运算符访问对象的属性。将使用类名访问类变量,如下所示 -

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

现在,将所有概念放在一起 -

现场演示
#!/usr/bin/python

class Employee:
   'Common 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

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

执行上述代码时,会产生以下结果 -

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

您可以随时添加、删除或修改类和对象的属性 -

emp1.age = 7  # Add an 'age' attribute.
emp1.age = 8  # Modify 'age' attribute.
del emp1.age  # Delete 'age' attribute.

您可以使用以下函数,而不是使用普通语句来访问属性 -

hasattr(emp1, 'age')    # Returns true if 'age' attribute exists
getattr(emp1, 'age')    # Returns value of 'age' attribute
setattr(emp1, 'age', 8) # Set attribute 'age' at 8
delattr(empl, 'age')    # Delete attribute 'age'

内置类属性

每个 Python 类都遵循内置属性,并且可以像任何其他属性一样使用点运算符访问它们 -

对于上面的类,让我们尝试访问所有这些属性 -

现场演示
#!/usr/bin/python

class Employee:
   'Common 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__

执行上述代码时,会产生以下结果 -

Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount':
<function displayCount at 0xb7c84994>, 'empCount': 2, 
'displayEmployee': <function displayEmployee at 0xb7c8441c>, 
'__doc__': 'Common base class for all employees', 
'__init__': <function __init__ at 0xb7c846bc>}

销毁对象(垃圾回收)

Python 会自动删除不需要的对象(内置类型或类实例)以释放内存空间。 Python 定期回收不再使用的内存块的过程称为垃圾收集。

Python 的垃圾收集器在程序执行期间运行,并在对象的引用计数达到零时触发。对象的引用计数随着指向它的别名数量的变化而变化。

对象的引用计数在被分配新名称或放置在容器(列表、元组或字典)中时会增加。使用 del 删除对象时,对象的引用计数会减少 ,它的引用被重新分配,或者它的引用超出范围。当一个对象的引用计数达到零时,Python 会自动收集它。

a = 40      # Create object <40>
b = a       # Increase ref. count  of <40> 
c = [b]     # Increase ref. count  of <40> 

del a       # Decrease ref. count  of <40>
b = 100     # Decrease ref. count  of <40> 
c[0] = -1   # Decrease ref. count  of <40> 

当垃圾收集器销毁孤立实例并回收其空间时,您通常不会注意到。但是一个类可以实现特殊方法__del__() ,称为析构函数,在实例即将被销毁时调用。此方法可用于清理实例使用的任何非内存资源。

示例

这个 __del__() 析构函数打印即将被销毁的实例的类名 -

现场演示
#!/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) # prints the ids of the obejcts
del pt1
del pt2
del pt3

执行上述代码时,会产生以下结果 -

3083401324 3083401324 3083401324
Point destroyed

注意 - 理想情况下,你应该在单独的文件中定义你的类,然后你应该使用 import 将它们导入你的主程序文件 声明。

类继承

无需从头开始,您可以通过在新类名后面的括号中列出父类,从预先存在的类派生类来创建类。

子类继承其父类的属性,您可以像在子类中定义这些属性一样使用这些属性。子类也可以覆盖父类的数据成员和方法。

语法

派生类的声明很像它们的父类;但是,在类名之后给出了要继承的基类列表 -

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

示例

现场演示
#!/usr/bin/python

class Parent:        # define parent class
   parentAttr = 100
   def __init__(self):
      print "Calling parent constructor"

   def parentMethod(self):
      print 'Calling parent method'

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

   def getAttr(self):
      print "Parent attribute :", Parent.parentAttr

class Child(Parent): # define child class
   def __init__(self):
      print "Calling child constructor"

   def childMethod(self):
      print 'Calling child method'

c = Child()          # instance of child
c.childMethod()      # child calls its method
c.parentMethod()     # calls parent's method
c.setAttr(200)       # again call parent's method
c.getAttr()          # again call parent's method

执行上述代码时,会产生以下结果 -

Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200

类似地,您可以从多个父类中驱动一个类,如下所示 -

class A:        # define your class A
.....

class B:         # define your class B
.....

class C(A, B):   # subclass of A and B
.....

您可以使用 issubclass() 或 isinstance() 函数来检查两个类和实例的关系。

覆盖方法

您始终可以覆盖您的父类方法。重写父类方法的原因之一是您可能希望子类中有特殊或不同的功能。

示例

现场演示
#!/usr/bin/python

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

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

c = Child()          # instance of child
c.myMethod()         # child calls overridden method

执行上述代码时,会产生以下结果 -

Calling child method

基础重载方法

下表列出了您可以在自己的类中覆盖的一些通用功能 -

Sr.No. 方法、描述和示例调用
1

__init__ ( self [,args...] )

构造函数(带有任何可选参数)

示例调用:obj =className(args)

2

__del__(自我)

析构函数,删除一个对象

示例调用:del obj

3

__repr__(自我)

可评估的字符串表示

示例调用:repr(obj)

4

__str__(自我)

可打印的字符串表示

示例调用:str(obj)

5

__cmp__ (self, x)

对象比较

示例调用:cmp(obj, x)

重载运算符

假设您创建了一个 Vector 类来表示二维向量,当您使用加号运算符将它们相加时会发生什么? Python 很可能会对你大喊大叫。

但是,您可以定义 __add__ 类中的方法来执行向量加法,然后加号运算符将按预期运行 -

示例

现场演示
#!/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

执行上述代码时,会产生以下结果 -

Vector(7,8)

数据隐藏

对象的属性在类定义之外可能可见,也可能不可见。您需要使用双下划线前缀命名属性,并且这些属性对于外人来说是不直接可见的。

示例

现场演示
#!/usr/bin/python

class JustCounter:
   __secretCount = 0
  
   def count(self):
      self.__secretCount += 1
      print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount

执行上述代码时,会产生以下结果 -

1
2
Traceback (most recent call last):
   File "test.py", line 12, in <module>
      print counter.__secretCount
AttributeError: JustCounter instance has no attribute '__secretCount'

Python 通过在内部更改名称以包含类名来保护这些成员。您可以访问诸如 object._className__attrName 之类的属性 .如果您将最后一行替换如下,那么它对您有用 -

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

执行上述代码时,会产生以下结果 -

1
2
2

Python

  1. C# 类和对象
  2. Python 数据类型
  3. Python 运算符
  4. Python pass 语句
  5. Python字典
  6. Python 自定义异常
  7. Python 面向对象编程
  8. Python 继承
  9. Java 单例类
  10. 自动视觉对象跟踪
  11. Python 中的 type() 和 isinstance() 示例
  12. Java - 对象和类