Python 类和对象怎么用?新手入门详解

文章导读
Previous Quiz Next Python 是一种 面向对象编程语言,这意味着它基于 OOP 概念的原则。Python 程序中使用的实体是一个或另一个 class 的 object。例如,数字、字符串、列表、字典以及程序中的其他类似实体都是相应内置 class 的对
📋 目录
  1. A Python 中的 Class 是什么?
  2. B 在 Python 中创建 Class
  3. C 什么是 Object?
  4. D 在 Python 中创建 Class 的 Object
  5. E Python 中访问对象属性
  6. F Python 中的内置类属性
  7. G Python 数据类型的内置类
  8. H Python 中的垃圾回收(销毁对象)
  9. I Python 中的数据隐藏
A A

Python - 类和对象



Previous
Quiz
Next

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

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

Python 中的 Class 是什么?

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

在 Python 中创建 Class

使用 class 关键字在 Python 中创建新 class。class 的名称紧跟在 class 关键字后面,后跟冒号,如下所示 −

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

  • class_suite 包含定义 class 成员、数据属性和函数的所有组件语句。

示例

以下是一个简单的 Python class 示例 −

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

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

  • 你像声明普通函数一样声明其他 class 方法,只是每个方法的第一个参数是 self。Python 会为你将 self 参数添加到列表中;调用方法时无需包含它。

什么是 Object?

object 指的是给定 Python class 的一个实例。每个 object 都有由其 class 定义的属性和方法。

创建 class 时,它仅描述了 object 的结构。当从 class 实例化 object 时,才会分配内存。

class object in python

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

在 Python 中创建 Class 的 Object

要创建 class 的实例,使用 class 名称调用 class,并传入其 __init__ 方法接受的任何参数。

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

Python 中访问对象属性

你可以使用点运算符通过对象来访问对象的属性。类变量将使用类名来访问,如下所示 −

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

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

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)

执行上述代码时,将产生以下结果 −

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

你可以在任何时候添加、删除或修改类和对象的属性 −

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

除了使用普通语句访问属性外,你还可以使用以下函数 −

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

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

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

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

# 如果 'age' 属性存在则返回 True
hasattr(emp1, 'age')   
# 返回 'age' 属性的值
getattr(emp1, 'age')    
# 将属性 'age' 设置为 8
setattr(emp1, 'age', 8) 
# 删除属性 'age'
delattr(empl, 'age')    

Python 中的内置类属性

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

SNo. Attributes & Description
1 __dict__

包含类命名空间的字典。

2 __doc__

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

3 __name__

类名

4 __module__

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

5 __bases__

一个可能为空的元组,包含基类,按照它们在基类列表中的出现顺序。

示例

对于上述 Employee 类,让我们尝试访问其属性 −

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__)

执行上述代码时,将产生以下结果 −

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 遵循面向对象编程范式。字符串、列表和数据类型等实体都属于某个内置 class。

如果我们想查看哪种数据类型属于哪个内置 class,可以使用 Python 的 type() function。这个 function 接受一个数据类型并返回其对应的 class。

示例

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

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

执行这段代码时,它将显示 Python 数据类型的对应 class −

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

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

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

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

当对象被赋予新名称或放入容器(list、tuple 或 dictionary)中时,其引用计数增加。当使用 del 删除它、其引用被重新赋值或其引用超出作用域时,引用计数减少。当对象的引用计数达到零时,Python 会自动收集它。

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

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

通常你不会注意到垃圾回收器何时销毁未使用的实例并回收其空间。但一个 class 可以实现特殊方法 __del__(),称为 destructor,当实例即将被销毁时调用。该方法可用于清理实例使用的非内存资源。

示例

__del__() destructor 会打印即将被销毁的实例的 class 名称,如下面的代码块所示 −

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

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

135007479444176 135007479444176 135007479444176
Point destroyed

Python 中的数据隐藏

对象的属性在 class 定义外部可能可见也可能不可见。你需要为属性命名时使用双下划线前缀,这样这些属性就不会直接对外部可见。

示例

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 通过在内部将名称更改为包含 class 名称的方式保护这些成员。你可以以 object._className__attrName 的形式访问此类属性。如果你将最后一行替换为以下内容,它就会正常工作 −

print(counter._JustCounter__secretCount)

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

1
2
2