类和对象

PythonBeginner
立即练习

介绍

在本实验中,你将学习 Python 中的类和对象。类(class)是创建对象的模板,而对象(object)是类的实例。

学习目标

  • 名称与对象
  • 作用域与命名空间
  • 实例对象
  • 方法对象
  • 继承
  • 私有变量
这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 高级 级别的实验,完成率为 35%。获得了学习者 100% 的好评率。

定义和创建类

在 Python 中定义类时,使用 class 关键字后跟类的名称。

类定义中应包含一个 __init__ 方法,这是 Python 中的一个特殊方法,当从类创建对象时会调用该方法。

打开一个新的 Python 解释器。

python3

以下是一个表示圆的类的示例:

class Circle:
    def __init__(self, radius):
        self.radius = radius

__init__ 方法接收一个参数 radius,并将其赋值给对象的 radius 属性。

实例化对象

要从类创建一个实例对象,你需要调用类名并加上括号。之所以称为“实例”,是因为它是类的具体表现。

circle1 = Circle(5)

这将创建一个类型为 Circle 的实例对象 circle1,其半径为 5。实例对象可用于存储特定于该对象的数据。例如,每个 Circle 对象可以有不同的半径。

在创建对象时,上一步中的 __init__ 方法会自动调用,对象的 radius 属性将被初始化为值 5

__init__ 方法通常用于设置对象的初始状态,例如初始化对象的属性或设置与外部资源的连接。它在对象创建时自动调用,因此你无需手动调用。

需要注意的是,__init__ 方法只是一个普通方法,可以有任何名称。然而,推荐的命名约定是使用 __init__,以明确表示它是类的初始化方法。

访问和修改属性

要访问对象的属性,请使用点符号(dot notation)。例如,要访问 circle1 对象的半径,可以使用以下代码:

print(circle1.radius) ## 输出:5

你可以通过为属性赋值来修改对象的属性。例如,要更改 circle1 对象的半径,可以使用以下代码:

circle1.radius = 10
print(circle1.radius) ## 输出:10

添加方法对象

方法(method)是定义在类内部的函数,用于对存储在对象属性中的数据进行操作。在 Python 中,方法使用 def 关键字定义,后跟方法名称和参数列表。

以下是在 Circle 类中定义的 area 方法的示例:

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius * self.radius

area 方法根据半径计算圆的面积。它通过使用 self.radius 属性来实现这一点,该属性引用调用方法的对象的半径。

要在对象上调用方法,请使用点符号后跟方法名称和括号。例如,要在 circle1 对象上调用 area 方法,可以使用以下代码:

circle1 = Circle(15)
print(circle1.area()) ## 输出:706.5

这将打印 circle1 对象的面积,它是 Circle 类的一个特定实例。

方法对于将功能封装在类中并提供一种操作对象属性中存储的数据的方式非常有用。

初学者应特别注意括号的使用。 括号用于在对象上调用方法,括号也用于向方法传递参数。这在最初可能会让人感到困惑,但随着你继续学习类和对象,这一点会变得更加清晰。

实例对象(Instance Objects)和方法对象(Method Objects)是 Python 中两种主要的对象类型。总结来说,实例对象是从类创建的,而方法对象是在类内部定义的。

继承

继承是一种创建新类的方式,新类是现有类的修改版本。新类称为子类(subclass),现有类称为父类(superclass)。

继承允许你创建一个子类,该子类具有父类的所有属性和方法,你还可以向子类添加额外的属性和方法,或者覆盖父类的属性和方法。

以下是一个继承自 Circle 类的子类 Cylinder 的示例:

class Cylinder(Circle):
    def __init__(self, radius, height):
        super().__init__(radius)
        self.height = height

Cylinder 类有一个 __init__ 方法,该方法接收两个参数:radiusheight。它使用 super() 函数调用 Circle 类的 __init__ 方法来初始化对象的 radius 属性,然后设置对象的 height 属性。

super() 函数是 Python 中的一个特殊函数,用于引用类的父类。它用于从子类内部调用父类的方法。

super() 函数在类定义中定义,并接收 self 参数,该参数引用正在创建的对象。根据调用的方法,它还可以接收其他参数。在此示例中,它将 radius 参数传递给 Circle 类的 __init__ 方法,并初始化对象的 radius 属性。

Cylinder 类现在具有 Circle 类的所有属性和方法,以及额外的 height 属性。你可以像使用 Circle 类一样,使用点符号访问 Cylinder 类的属性和方法。

例如,你可以创建一个 Cylinder 对象并访问其属性,如下所示:

cylinder1 = Cylinder(5, 10)
print(cylinder1.radius)  ## 输出 5
print(cylinder1.height)  ## 输出 10

继承是面向对象编程中的一个有用特性,因为它允许你重用代码并创建类的层次结构。

super() 函数

当你希望在子类中重用父类的代码并扩展其功能时,super() 函数非常有用。

需要注意的是,super() 函数并不是对父类的静态引用。它是一个动态引用,会根据调用它的类而变化。这使你可以在多级继承中使用继承,并在每一级访问正确的父类。

例如,考虑以下类:

class A:
    def method(self):
        print("A method")

class B(A):
    def method(self):
        super().method()
        print("B method")

class C(B):
    def method(self):
        super().method()
        print("C method")

在这里,CB 的子类,而 BA 的子类。如果你在 C 对象上调用 method 方法,它将首先使用 super() 函数调用 A 类的 method 方法,然后使用 super() 函数调用 B 类的 method 方法,最后调用 C 类的 method 方法。

obj = C()
obj.method()  ## 输出 "A method", "B method", "C method"

super() 函数是面向对象编程中的一个有用特性,它允许你重用代码并创建类的层次结构。

私有变量

在 Python 中,私有变量是指只能在定义它们的类内部使用,而不能被外部代码访问的变量。私有变量不能直接从类外部访问。

要在 Circle 类中定义私有变量,可以使用双下划线前缀 (__) 后跟变量名。例如:

class Circle:
    def __init__(self, radius):
        self.__radius = radius

这将在 Circle 类中定义一个私有变量 __radius

私有变量只能在定义它们的类内部使用。它们不能直接从类外部访问。例如,如果你尝试从 Circle 类外部访问 __radius 变量,将会引发错误:

circle1 = Circle(5)
print(circle1.__radius)  ## 这将引发 AttributeError

私有变量对于将数据封装在类内部并限制外部代码修改的能力非常有用。然而,需要注意的是,私有变量在 Python 中并不是真正私有的,仍然可以通过“名称改写”(name mangling)从类外部访问。

名称改写是一种技术,它通过在变量名前添加特殊前缀,使其更难从类外部访问。

例如,仍然可以使用以下语法从 Circle 类外部访问 __radius 变量:

print(circle1._Circle__radius)  ## 这将输出 5

然而,这并不是一种良好的编程实践,应尽量避免。

相反,你应该仅在定义私有变量的类内部使用它们,并在必要时提供公共方法来访问或修改数据。

以下是一个带有私有 __radius 变量以及用于访问和修改半径的公共方法的 Circle 类的示例:

class Circle:
    def __init__(self, radius):
        self.__radius = radius

    def get_radius(self):
        return self.__radius

    def set_radius(self, radius):
        self.__radius = radius

要访问 Circle 对象的半径,可以使用 get_radius 方法:

circle1 = Circle(5)
print(circle1.get_radius())  ## 输出 5

要修改 Circle 对象的半径,可以使用 set_radius 方法:

circle1.set_radius(10)
print(circle1.get_radius())  ## 输出 10

总结

在本实验中,你学习了 Python 中的类和对象。你学习了如何定义一个类、从类创建对象、访问对象的属性和方法、修改对象的属性,以及创建一个继承自父类的子类。

以下是本实验涵盖的主要概念的总结:

  • 类(class)是创建对象的模板。对象(object)是类的实例。
  • __init__ 方法在从类创建对象时被调用。它允许你设置对象的属性。
  • 你可以使用点符号访问对象的属性,并使用点符号后跟方法名称和括号来调用对象的方法。
  • 你可以通过为属性分配新值来修改对象的属性。
  • 继承允许你创建一个父类的修改版本作为子类。子类可以覆盖或扩展父类的方法。

希望本实验能帮助你学习 Python 的类和对象。如果你有任何问题,请告诉我!