Python - 类和对象



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

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

什么是 Python 中的类?

在 Python 中,类是用户定义的实体(数据类型),用于定义对象可以包含的数据类型以及它可以执行的操作。它用作创建对象的模板。例如,如果我们想在 Python 程序中为 Smartphone 定义一个类,我们可以使用 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 是一个类变量,其值在 this 类的所有实例之间共享。这可以作为 Employee.empCount 从类内部或类外部访问。
  • 第一个方法 __init__() 是一个特殊方法,它称为类构造函数或初始化方法,Python 在创建此类的新实例时调用该方法。
  • 您可以像普通函数一样声明其他类方法,但每个方法的第一个参数是 self。Python 将 self 参数添加到列表中;在调用方法时,不需要包含它。

什么是对象?

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

创建类时,它仅描述 obejcts 的结构。当从类实例化对象时,将分配内存。

Python 中的 class 对象

在上图中,Vehicle 是类名,Car、Bus SUV 是其对象。

在 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 	

除了使用 normal 语句访问属性外,您还可以使用以下函数 -

  • getattr(obj, name[, default]) − 来访问 Object 的属性。
  • hasattr(obj,name) − 来检查属性是否存在。
  • setattr(obj,name,value) − 设置属性。如果 attribute 不存在,则将创建它。
  • 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 类都遵循内置属性,并且可以像任何其他属性一样使用点运算符访问它们 -

属性 描述
__dict__ 包含类的命名空间的 Dictionary。
__doc__ 类 documentation 字符串或 none(如果未定义)。
__name__ 类名
__module__ 定义类的模块名称。此属性在交互模式下为 “__main__”。
__bases__ 一个可能为空的 Tuples,其中包含基类,按它们在基类列表中出现的顺序。 

对于上面的 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 = "qikepu"
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