返回

学会在 Python 中正确使用类:常见的反例

人工智能

在之前的文章中,我们讨论了在 Python 中使用类的启发式方法。启发式方法是一种帮助我们做出决策的简单规则,但它们并不总是有效。为了最大限度地利用它们,了解什么是例外情况是有帮助的。

让我们看看几个现实世界的例子,在这些例子中,使用类并不能带来好处,甚至会导致代码的混乱和难以维护。

1. 过度使用类

过度使用类是最常见的反例之一。当我们看到一个问题时,我们倾向于用类来解决它。然而,这并不总是最好的解决方案。

例如,假设我们有一个函数,它接受一个列表并返回列表中的最大值。我们可以使用类来实现这个函数,如下所示:

class MaxFinder:
    def __init__(self, lst):
        self.lst = lst

    def find_max(self):
        max_value = self.lst[0]
        for value in self.lst:
            if value > max_value:
                max_value = value
        return max_value


lst = [1, 2, 3, 4, 5]
max_finder = MaxFinder(lst)
max_value = max_finder.find_max()
print(max_value)

这个类可以用来找到列表中的最大值,但它并不是最好的解决方案。因为,我们也可以使用内置的 max() 函数来实现这个功能,如下所示:

lst = [1, 2, 3, 4, 5]
max_value = max(lst)
print(max_value)

max() 函数的功能与 MaxFinder 类完全相同,但它不需要我们创建类实例,也不需要编写 find_max() 方法。

2. 不恰当地使用类

另一个常见的反例是不恰当地使用类。例如,我们可能使用类来表示一个数据结构,但实际上我们并不需要类提供的功能。

例如,假设我们有一个链表,我们可以使用类来表示链表中的每个节点,如下所示:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


class LinkedList:
    def __init__(self):
        self.head = None

    def add_node(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current_node = self.head
            while current_node.next is not None:
                current_node = current_node.next
            current_node.next = new_node


lst = LinkedList()
lst.add_node(1)
lst.add_node(2)
lst.add_node(3)

这个类可以用来表示链表,但实际上我们并不需要类提供的功能。因为,我们也可以使用内置的列表来实现链表,如下所示:

lst = [1, 2, 3]

列表的功能与链表完全相同,但它不需要我们创建类实例,也不需要编写 add_node() 方法。

3. 滥用继承

滥用继承是另一个常见的反例。例如,我们可能从一个类继承,但实际上我们并不需要继承该类的功能。

例如,假设我们有一个 Animal 类,它表示动物的通用行为,如下所示:

class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")


class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)

    def bark(self):
        print(f"{self.name} is barking.")


class Cat(Animal):
    def __init__(self, name):
        super().__init__(name)

    def meow(self):
        print(f"{self.name} is meowing.")

这个类可以用来表示动物的通用行为,但实际上我们并不需要继承该类的功能。因为,我们可以直接创建 DogCat 类,如下所示:

class Dog:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")

    def bark(self):
        print(f"{self.name} is barking.")


class Cat:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} is eating.")

    def sleep(self):
        print(f"{self.name} is sleeping.")

    def meow(self):
        print(f"{self.name} is meowing.")

DogCat 类具有与 Animal 类相同的功能,但它们不需要继承 Animal 类。

结论

在 Python 中使用类时,我们需要考虑以下几点:

  • 不要过度使用类。
  • 不要不恰当地使用类。
  • 不要滥用继承。

如果我们遵循这些原则,我们就可以避免使用类的常见反例,编写出健壮、可维护的代码。