介绍
在这个实验中,你将学习 Python 中面向对象编程(OOP)的基本概念。我们将探讨如何定义类(class),类是创建对象的蓝图,并理解类与对象之间的关系。
你将通过创建和使用自己定义的类的实例来获得实践经验。本实验将指导你使用 __init__ 方法初始化对象以设置其初始状态,并使用 __repr__ 方法自定义对象的字符串表示形式,以提高调试和可读性。
在这个实验中,你将学习 Python 中面向对象编程(OOP)的基本概念。我们将探讨如何定义类(class),类是创建对象的蓝图,并理解类与对象之间的关系。
你将通过创建和使用自己定义的类的实例来获得实践经验。本实验将指导你使用 __init__ 方法初始化对象以设置其初始状态,并使用 __repr__ 方法自定义对象的字符串表示形式,以提高调试和可读性。
在这一步中,你将学习如何定义一个基础类并从中创建一个对象,即实例(instance)。
在面向对象编程中,**类(class)**是创建对象的蓝图。它定义了一组属性(数据)和方法(函数),被创建的对象将拥有这些属性和方法。**对象(object)**是类的实例,是根据类蓝图构建的具体实体。
让我们从创建一个简单的 Dog 类开始。
首先,从 WebIDE 左侧的文件浏览器中打开 dog.py 文件。该文件目前是空的。
现在,将以下代码添加到 dog.py 中,以定义 Dog 类,创建一个实例并使用它:
## Define a simple Dog class
class Dog:
## Class attribute
species = "Canis familiaris"
## Method
def bark(self):
print("Woof!")
## Create an instance (object) of the Dog class
my_dog = Dog()
## Access the class attribute using the instance
print(f"The species is: {my_dog.species}")
## Call the instance's method
print("The dog says:")
my_dog.bark()
我们来分解一下这段代码:
class Dog:: 此行定义了一个名为 Dog 的新类。species = "Canis familiaris": 这是一个类属性(class attribute)。它的值在 Dog 类的所有实例之间共享。def bark(self):: 这定义了一个方法(method),它是类中的一个函数。self 参数是对当前类实例的引用,用于访问属于该类的变量。my_dog = Dog(): 此行创建了 Dog 类的一个新实例,并将其赋值给变量 my_dog。my_dog.species: 我们使用点表示法(dot notation)访问 my_dog 对象的 species 属性。my_dog.bark(): 我们在 my_dog 对象上调用 bark 方法。Python 会自动将 my_dog 对象作为 self 参数传递给该方法。保存文件。要运行你的脚本,请在 WebIDE 中打开一个终端(terminal),并执行以下命令:
python dog.py
你应该会看到以下输出,确认你的对象已成功创建,并且其属性和方法已被正确访问。
The species is: Canis familiaris
The dog says:
Woof!
__init__ 方法初始化对象虽然类属性(class attributes)被所有实例共享,但你通常希望每个实例都有自己独特的(unique)数据。__init__ 方法是 Python 类中的一个特殊方法,它充当构造函数(constructor)。当你创建一个新实例时,它会被自动调用,允许你初始化其独特的属性。
让我们修改 Dog 类,为每只狗赋予一个唯一的名称(name)和品种(breed)。
再次打开 dog.py 文件,并用以下代码替换其内容:
## Define a Dog class with an __init__ method
class Dog:
## Class attribute
species = "Canis familiaris"
## The __init__ method (constructor)
def __init__(self, name, breed):
## Instance attributes
self.name = name
self.breed = breed
## Method
def bark(self):
print("Woof!")
## Create instances with unique attributes
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Lucy", "Labrador")
## Access the instance attributes
print(f"{dog1.name} is a {dog1.breed}.")
print(f"{dog2.name} is a {dog2.breed}.")
## The class attribute is still shared
print(f"Both are of the species: {dog1.species}")
以下是发生的变化:
def __init__(self, name, breed):: 我们定义了 __init__ 方法。它接收 self、name 和 breed 作为参数。self.name = name 和 self.breed = breed: 这些行创建了实例属性(instance attributes)。它们对每个 Dog 对象都是唯一的。self 关键字将这些属性附加到正在创建的特定实例上。dog1 = Dog("Buddy", "Golden Retriever"): 创建实例时,我们现在为 name 和 breed 传递了参数。这些参数会自动传递给 __init__ 方法。保存文件并通过终端运行它:
python dog.py
输出显示每只狗对象都有自己的名称和品种,同时仍然共享类属性 species。
Buddy is a Golden Retriever.
Lucy is a Labrador.
Both are of the species: Canis familiaris
__repr__ 自定义对象表示当你直接尝试打印一个对象时,Python 会显示一个默认的表示(representation),其中包含对象的类名和内存地址,这通常没有太大帮助。你可以通过定义 __repr__ 特殊方法,提供一个更具描述性且对开发者更友好的字符串表示。
让我们向 Dog 类添加一个 __repr__ 方法。
打开 dog.py 并用我们代码的最终版本替换其内容:
## Define a Dog class with __init__ and __repr__ methods
class Dog:
## Class attribute
species = "Canis familiaris"
## The __init__ method (constructor)
def __init__(self, name, breed):
self.name = name
self.breed = breed
## The __repr__ method for a developer-friendly representation
def __repr__(self):
return f"Dog(name='{self.name}', breed='{self.breed}')"
## Method
def bark(self):
print("Woof!")
## Create an instance
my_dog = Dog("Buddy", "Golden Retriever")
## Print the object directly
print(my_dog)
关键的新增部分是:
def __repr__(self):: 这定义了表示方法。return f"Dog(name='{self.name}', breed='{self.breed}')": 此方法应返回一个字符串。一个好的做法是使该字符串看起来像一个有效的 Python 表达式,该表达式可用于以相同状态重新创建对象。保存文件并最后一次运行脚本:
python dog.py
输出不再是内存地址,而是你的 __repr__ 方法返回的清晰、信息丰富的字符串。这对于调试(debugging)极其有用。
Dog(name='Buddy', breed='Golden Retriever')
在这个实验(Lab)中,你学习了 Python 中面向对象编程(Object-Oriented Programming)的基础知识。你从定义一个简单的类并创建其实例开始,学习了如何使用类属性(class attributes)和方法(methods)。然后,你通过添加 __init__ 方法来初始化每个对象,赋予其独特的实例属性(instance attributes),从而增强了你的类。最后,你通过实现 __repr__ 方法来自定义了对象的字符串表示形式,这极大地提高了代码的清晰度和可调试性(debuggability)。这些概念是使用 Python 构建更复杂和更有条理的应用程序的基础。