简介
Python 是一种面向对象的编程语言。面向对象编程(OOP)侧重于创建可重用的代码模式,与过程式编程相反,后者侧重于显式的顺序指令。特别是在处理复杂程序时,面向对象编程使您能够重用代码并编写更易读的代码,从而使其更易于维护。
面向对象编程中最重要的概念之一是类和对象的区别,其定义如下:
- 类 —— 由程序员为对象创建的蓝图。这定义了将表征从该类实例化的任何对象的一组属性。
- 对象 —— 类的一个实例。这是类的实现版本,在程序中体现出来。
这些用于创建模式(对于类)然后利用这些模式(对于对象)。
在本教程中,我们将介绍创建类、实例化对象、使用构造方法初始化属性以及处理同一类的多个对象。
先决条件
您应该已经安装了 Python 3,并在计算机或服务器上设置了编程环境。如果您尚未设置编程环境,可以参考适用于您的操作系统(Ubuntu、CentOS、Debian 等)的本地编程环境或服务器编程环境的安装和设置指南。
类
类就像一个蓝图或原型,您可以定义它来创建对象。
我们使用 class
关键字来定义类,类似于我们使用 def
关键字来定义函数。
让我们定义一个名为 Shark
的类,其中有两个与之关联的函数,一个用于游泳,另一个用于展现其惊人之处:
class Shark:
def swim(self):
print("The shark is swimming.")
def be_awesome(self):
print("The shark is being awesome.")
因为这些函数是缩进在 Shark
类下面的,它们被称为方法。方法是在类内部定义的一种特殊类型的函数。
这些函数的参数是单词 self
,它是对基于该类创建的对象的引用。要引用类的实例(或对象),self
将始终是第一个参数,但它不一定是唯一的参数。
定义这个类并没有创建任何 Shark
对象,只是为我们可以稍后定义的 Shark
对象提供了一个模式。也就是说,如果您在此阶段运行上面的程序,将不会返回任何内容。
上面创建的 Shark
类为我们提供了一个对象的蓝图。
对象
对象是类的一个实例。我们可以使用上面定义的 Shark
类来创建一个对象或其实例。
我们将创建一个名为 sammy
的 Shark
对象:
sammy = Shark()
在这里,我们通过将其设置为 Shark()
来初始化对象 sammy
作为类的一个实例。
现在,让我们使用 Shark
对象 sammy
的两个方法:
sammy = Shark()
sammy.swim()
sammy.be_awesome()
Shark
对象 sammy
使用了 swim()
和 be_awesome()
两个方法。我们使用点运算符(.
)调用这些方法,该运算符用于引用对象的属性。在这种情况下,属性是一个方法,并且它使用括号调用,就像调用函数一样。
因为关键字 self
是方法在 Shark
类中定义的参数,所以 sammy
对象被传递给这些方法。self
参数确保方法有一种引用对象属性的方式。
但是,当我们调用方法时,括号内没有传递任何内容,对象 sammy
是自动通过点运算符传递的。
让我们将对象添加到程序的上下文中:
class Shark:
def swim(self):
print("The shark is swimming.")
def be_awesome(self):
print("The shark is being awesome.")
def main():
sammy = Shark()
sammy.swim()
sammy.be_awesome()
if __name__ == "__main__":
main()
让我们运行程序看看它的作用:
python shark.py
The shark is swimming.
The shark is being awesome.
对象 sammy
在程序的 main()
函数中调用了两个方法,导致这些方法运行。
构造方法
构造方法用于初始化数据。它在类的对象实例化时立即运行。也称为 __init__
方法,它将是类的第一个定义,并且看起来像这样:
class Shark:
def __init__(self):
print("This is the constructor method.")
如果您在上面的程序中添加了上述 __init__
方法,程序将在不修改 sammy
实例化内部的任何内容的情况下输出以下内容:
This is the constructor method.
The shark is swimming.
The shark is being awesome.
这是因为构造方法会自动初始化。您应该使用此方法来执行您希望对类对象进行的任何初始化。
与上面的构造方法不同,让我们创建一个使用 name
变量的构造方法,我们可以使用它来为对象分配名称。我们将 name
作为参数传递,并将 self.name
设置为 name
:
class Shark:
def __init__(self, name):
self.name = name
接下来,我们可以修改我们的函数中的字符串以引用名称,如下所示:
class Shark:
def __init__(self, name):
self.name = name
def swim(self):
# 引用名称
print(self.name + " is swimming.")
def be_awesome(self):
# 引用名称
print(self.name + " is being awesome.")
最后,我们可以通过将其作为 Shark
类的参数传递来将 Shark
对象 sammy
的名称设置为 "Sammy"
:
class Shark:
def __init__(self, name):
self.name = name
def swim(self):
print(self.name + " is swimming.")
def be_awesome(self):
print(self.name + " is being awesome.")
def main():
# 设置 Shark 对象的名称
sammy = Shark("Sammy")
sammy.swim()
sammy.be_awesome()
if __name__ == "__main__":
main()
现在我们可以运行程序:
python shark.py
Sammy is swimming.
Sammy is being awesome.
我们看到我们传递给对象的名称被打印出来。我们使用带有参数名称的 __init__
方法定义了变量(以及 self
关键字)。
因为构造方法会自动初始化,我们不需要显式调用它,只需要在创建类的新实例时在类名后面的括号中传递参数。
如果我们想添加另一个参数,比如 age
,我们也可以通过将其传递给 __init__
方法来这样做:
class Shark:
def __init__(self, name, age):
self.name = name
self.age = age
然后,当我们创建我们的对象 sammy
时,我们可以在语句中传递 Sammy 的年龄:
sammy = Shark("Sammy", 5)
要使用 age
,我们还需要在类中创建一个调用它的方法。
构造方法允许我们初始化对象的某些属性。
处理多个对象
类很有用,因为它们允许我们基于相同的蓝图创建许多相似的对象。
为了了解这是如何工作的,让我们在我们的程序中添加另一个 Shark
对象:
class Shark:
def __init__(self, name):
self.name = name
def swim(self):
print(self.name + " is swimming.")
def be_awesome(self):
print(self.name + " is being awesome.")
def main():
sammy = Shark("Sammy")
sammy.be_awesome()
stevie = Shark("Stevie")
stevie.swim()
if __name__ == "__main__":
main()
我们创建了第二个名为 stevie
的 Shark
对象,并将名称 "Stevie"
传递给它。在这个例子中,我们使用 sammy
的 be_awesome()
方法和 stevie
的 swim()
方法。
让我们运行程序:
python shark.py
Sammy is being awesome.
Stevie is swimming.
输出显示我们正在使用两个不同的对象,sammy
对象和 stevie
对象,它们都是 Shark
类的对象。
类使得可以在不从头开始创建每个对象的情况下创建多个遵循相同模式的对象成为可能。
结论
本教程介绍了创建类、实例化对象、使用构造方法初始化属性以及处理同一类的多个对象。
面向对象编程是一个重要的概念,因为它使代码重用成为可能,因为为一个程序创建的对象可以在另一个程序中使用。面向对象的程序还使得程序设计更好,因为复杂的程序很难编写并且需要仔细的规划,这反过来使得随着时间的推移更少的工作来维护程序。## 结论
本教程介绍了创建类、实例化对象、使用构造方法初始化属性以及处理同一类的多个对象。
面向对象编程是一个重要的概念,因为它能够实现代码重用,一个程序中创建的对象可以在另一个程序中使用。面向对象的程序设计也能够实现更好的程序设计,因为复杂的程序很难编写,需要仔细的规划,这反过来又能减少后期维护程序的工作量。