Python - 类和对象



Python 是一种面向对象编程语言,这意味着它基于 OOP 概念的原则。Python 程序中使用的实体是某个类的对象。例如,数字、字符串、列表、字典以及程序中类似的其他实体都是相应内置类的对象。

在 Python 中,名为Object的类是所有类的基类或父类,包括内置类和用户定义类。

什么是 Python 中的类?

在 Python 中,class 是用户定义的实体(数据类型),它定义了对象可以包含的数据类型以及可以执行的操作。它用作创建对象的模板。例如,如果我们想在 Python 程序中定义一个智能手机类,我们可以使用 RAM、ROM、屏幕尺寸等数据类型以及拨打电话和发送短信等操作。

在 Python 中创建类

使用class 关键字在 Python 中创建一个新类。class关键字后紧跟类名,然后是一个冒号,如下所示:

class ClassName:
   'Optional class documentation string'
   class_suite
  • 该类具有一个文档字符串,可以通过 ClassName.__doc__ 访问。

  • 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
  • 变量empCount 是一个类变量,其值在该类的所有实例之间共享。可以从类内或类外作为Employee.empCount访问。

  • 第一个方法__init__()是一个特殊方法,称为类构造函数或初始化方法,当创建此类的新的实例时,Python 会调用它。

  • 您可以像声明普通函数一样声明其他类方法,区别在于每个方法的第一个参数是self。Python 会为您添加self 参数;调用方法时,不需要包含它。

什么是对象?

一个对象被称为给定Python类的实例。每个对象都有自己的属性和方法,这些属性和方法由其类定义。

创建类时,它只描述对象的结构。当从类实例化对象时,才会分配内存。

class object in python

在上图中,Vehicle是类名,CarBusSUV是它的对象。

在Python中创建类的对象

要创建类的实例,可以使用类名调用类,并传入其__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)

在Python中访问对象的属性

可以使用点运算符 object. 来访问对象的属性。类变量的访问方式如下:

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

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

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

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

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

除了使用正常的语句访问属性外,还可以使用以下函数:

  • getattr(obj, name[, default]) − 访问对象的属性。

  • hasattr(obj,name) − 检查属性是否存在。

  • setattr(obj,name,value) − 设置属性。如果属性不存在,则会创建它。

  • delattr(obj, name) − 删除属性。

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

Python中的内置类属性

每个Python类都保留以下内置属性,可以使用点运算符像任何其他属性一样访问它们:

序号 属性和描述
1 __dict__

包含类命名空间的字典。

2 __doc__

类文档字符串,如果未定义则为None。

3 __name__

类名

4 __module__

定义类的模块名。在交互模式下,此属性为“__main__”。

5 __bases__

一个可能为空的元组,包含基类,其顺序与其在基类列表中的出现顺序相同。

示例

对于上面的Employee类,让我们尝试访问它的属性:

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的type()函数。此函数接受数据类型并返回其对应的类。

示例

以下示例演示如何检查给定数据类型的内置类。

num = 20
print (type(num))
num1 = 55.50
print (type(num1))
s = "TutorialsPoint"
print (type(s))
dct = {'a':1,'b':2,'c':3}
print (type(dct))
def SayHello():
   print ("Hello World")
   return
print (type(SayHello))

执行此代码时,它将显示Python数据类型的对应类:

<class 'int'>
<class 'float'>
<class 'str'>
<class 'dict'>
<class 'function'>

Python中的垃圾回收(销毁对象)

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

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

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

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

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

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

示例

__del__()析构函数打印即将被销毁的实例的类名,如下面的代码块所示:

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
# prints the ids of the obejcts
print (id(pt1), id(pt2), id(pt3))
del pt1
del pt2
del pt3

执行后,上述代码将产生以下结果:

135007479444176 135007479444176 135007479444176
Point destroyed

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
ERROR!
Traceback (most recent call last):
  File <main.py>", line 11, in <module>
AttributeError: 'JustCounter' object has no attribute '__secretCount'

Python 通过在内部更改名称以包含类名来保护这些成员。您可以访问这些属性,例如 object._className__attrName。如果将最后一行替换为以下内容,则它对您有效:

print(counter._JustCounter__secretCount)

执行上述代码后,将产生以下结果:

1
2
2
广告