in

Python中的类:完全解释

谈到面向对象编程语言,python是一种相对简单的语言,可以用来实现类。使用类是实现封装、继承和多态性的关键因素,同时也使你的代码更加模块化。无论你的经验水平如何,理解类对于帮助你编写更好、更清晰的代码非常有用。在本文中,我们将介绍python中的类是什么,类的类型以及如何使用它们。

python中的类是什么?

你可以将类看作是用来创建对象的模板或蓝图。这是一个通用的术语,而对象的特定实例则被称为实例。因此,实例是类的特定实现,具有自己的属性和行为。

例如,如果你想记录汽车销售中心销售的汽车类型,你可以用“cars”类来表示这些汽车。在这个类中,我们可以定义属性,如颜色、型号、速度、年份等。然后可以创建多个实例来表示特定的汽车类型,这些实例可以与类中定义的任何方法一起使用。或者更简单地说,类可以被看作是一个通用的房屋蓝图,从这个蓝图建造的每个房屋都是一个类对象。在高层次上,对象的行为由其方法表示,而对象的状态则由其属性表示。

创建和定义类

创建类并不太复杂,总是以使用“class”关键字开始,后面跟着类名,每个单词首字母大写。我们通常在这之后定义“__init__()”方法,用于初始化我们创建的任何对象的属性。我们也可以在这个阶段定义类方法和共享属性。使用我们的汽车示例,我们可以创建如下的类:

class car(汽车):
    def __init__(self, make, model, year, color):
        self.make = make
        self.model = model
        self.year = year
        self.color = color
        self.is_running = false
        self.speed = 0

    def start_engine(self):
        if not self.is_running:
            self.is_running = true
            print("engine has started.")
        else:
            print("engine is already running.")

    def stop_engine(self):
        if self.is_running:
            self.is_running = false
            self.speed = 0
            print("engine has stopped.")
        else:
            print("engine is already stopped.")

    def accelerate(self, increment):
        if self.is_running:
            self.speed += increment
            print(f"accelerated. current speed: {self.speed} km/h.")
        else:
            print("cannot accelerate. engine is not running.")

    def brake(self, decrement):
        if self.is_running:
            if self.speed - decrement >= 0:
                self.speed -= decrement
                print(f"braked. current speed: {self.speed} km/h.")
            else:
                self.speed = 0
                print("car stopped.")
        else:
            print("cannot brake. engine is not running.")

    def display_info(self):
        print("car information:")
        print(f"make: {self.make}")
        print(f"model: {self.model}")
        print(f"year: {self.year}")
        print(f"color: {self.color}")
        print(f"speed: {self.speed} km/h")
        status = "running" if self.is_running else "stopped"
        print(f"status: {status}")

car1 = car("toyota", "camry", 2022, "silver")
car2 = car("honda", "accord", 2021, "black")

car1.start_engine()
car1.accelerate(20)
car1.brake(5)
car1.display_info()

car2.start_engine()
car2.accelerate(30)
car2.brake(10)
car2.stop_engine()
car2.display_info()

首先,我们定义了“car(汽车)”类和“__init__()”构造方法。它接受“model(型号)”,“year(年份)”,“make(制造商)”和“color(颜色)”参数,以及引用所创建实例的“self”。然后,我们使用“self.[parameter]”语法将参数值分配给实例属性。还初始化了两个额外的属性,表示引擎的状态和汽车的整体速度。

然后,在类内定义了一些方法。这些方法检查引擎是否已启动或停止,并提供增加或减少汽车速度的功能。我们还定义了“display_info()”方法,用于打印汽车实例的各种属性。

最后,我们创建了两个类的实例,对每个实例调用了一些方法,并打印了结果,如图所示。

在python中,使用“class”关键字定义类。

类属性 vs. 实例属性

我们已经简要介绍了类、属性和实例的概念,但是区分类属性和实例属性是一个好主意。类属性在类内部定义,但不在任何类方法内部定义。它们也被所有我们创建的类对象的实例共享,并且可以通过使用类名或任何实例来访问。另一方面,实例属性是每个实例特有的,在“__init__()”方法内部定义。每个实例都有自己的这些属性的副本。通过类或实例本身来访问和修改类和实例属性。在我们之前的例子中,我们在car类中定义的所有属性都是实例属性,因为它们是在构造方法内部定义的,每个实例都有自己的一组这些属性。

为了说明区别,考虑以下代码:

class car:
    total_cars = 0

    def __init__(self, make, model):
        self.make = make
        self.model = model
        car.total_cars += 1

car1 = car("toyota", "camry")
car2 = car("honda", "accord")

print(car1.total_cars)
print(car.total_cars)

print(car1.make)
print(car1.model)

print(car2.make)
print(car2.model)

我们这里有相同的类,以及一些实例属性,“make”和“model”。然而,我们还有类属性“total_cars”,用于跟踪创建的汽车数量。因此,它是在任何类方法之外定义的。首先,我们通过“car1”实例访问类属性,然后直接访问它,每次打印相同的结果。最后,我们打印两个实例的“make”和“model”属性,如图所示。

类属性在实例之间共享,而实例属性对每个实例都是特定的。

©jingzhengli.com

python中的类的类型

python中有许多不同类型的类。我们已经介绍了标准类,但其他常见类型包括抽象类、元类、派生类、单例类和混合类。下面简要介绍这些。

抽象类

抽象类之所以被称为抽象类,是因为它们不能直接实例化,而只提供其他类用于实现方法和接口的蓝图。它们通常包含没有实现的抽象方法。

虽然python没有明确的抽象关键字,但我们可以使用“abc”类来创建抽象类,以及一个修饰符来修改类。例如,我们有以下代码:

from abc import abc, abstractmethod

class abstractclass(abc):
    @abstractmethod
    def abstract_method(self):
        pass

    def regular_method(self):
        print("this is a regular method.")

class concreteclass(abstractclass):
    def abstract_method(self):
        print("implementation of abstract_method.")

obj = concreteclass()
obj.abstract_method()
obj.regular_method()

我们定义了“abstractclass”类和方法“abstract_method()”。我们还定义了一个常规方法“regular_method()”,并创建了“concreteclass”类,其中包含抽象方法的实现。最后,创建了此类的一个实例,调用了两个方法,并打印了结果。

抽象类提供方法,但没有实现。

©jingzhengli.com

元类

元类允许您定义其他类的行为,通常指示它们应该如何创建。以这种方式,元类可以被视为类的类,它们可以相当复杂。但是,在之前的示例中已经展示了一个元类的示例;“abc”元类用于创建和定义抽象类,并将特定方法标记为抽象。

派生类

派生类是从另一个类继承行为、方法和属性的类。它们可以通过添加额外的方法或属性来扩展基类,甚至通过覆盖其他方法来扩展基类。请注意,前面示例中的“concreteclass”类实际上不是派生类,因为它仅为抽象类提供了特定的实现。以一个简单的示例为例,请看以下代码块:

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

    def speak(self):
        print("the animal makes a sound.")

class dog(animal):
    def speak(self):
        print("the dog barks.")

animal = animal("generic animal")
animal.speak()

dog = dog("fido")
dog.speak()

我们有基类“animal”,还有派生类“dog”,它包含了自己对“speak()”方法的实现。我们创建了一个基类的实例,将其分配给“animal”变量,并打印通用信息。然后,我们创建一个派生类的实例,将其分配给“dog”变量,并在该对象上调用speak方法。这将打印出一个特定的消息,我们也可以在图片中的控制台中看到。

派生类被设计用来继承基类的方法和属性。

©jingzhengli.com

单例类

单例类是将实例的创建限制为单个实例的类。当我们希望能够在资源需要共享时,使用不同的对象全局访问此实例,并且希望控制初始化时,它们通常被使用。使用全局状态可能会让代码变得不够模块化,但是单例类确实有它们的应用。下面是一个简单的示例:

class singleton:
    _instance = none

    def __new__(cls):
        if cls._instance is none:
            cls._instance = super().__new__(cls)
        return cls._instance

singleton1 = singleton()
singleton2 = singleton()

print(singleton1 is singleton2)

我们创建了“singleton”类,并定义了“__new__()”方法,它控制实例的创建。该方法检查“_instance”变量是否为none,如果是,则使用“super().__new__(cls)”方法创建一个实例。当我们创建后续实例时,将返回现有的实例。最后,我们创建了两个实例“singleton1”和“singleton2”,并检查它们是否相同。通过“true”输出,它们被证明是相同的,正如我们在图片中看到的那样。

单例类只允许创建类对象的一个实例。

©jingzhengli.com

混合类

如果我们需要额外的功能,但又不想使用继承,混合类为我们提供了另一种实现这一目的的方式。混合类是一种被设计为与其他类“混合”的类,以便可以继承它们的属性。通过这种方式,混合类为其他类添加了额外的功能。通常,每个混合类为类提供了一个特定的功能,而不会打断层次结构,这有助于使我们的代码模块化和可定制化。举个例子,考虑下面的代码:

class flymixin:
    def fly(self):
        print("flying...")

class swimmixin:
    def swim(self):
        print("swimming...")

class bird(flymixin):
    pass

class duck(flymixin, swimmixin):
    pass

bird = bird()
bird.fly()

duck = duck()
duck.fly()
duck.swim()

我们首先创建了混合类“flymixin”,并确保为易于识别添加了mixin作为后缀。在这个类内部,我们定义了“fly()”方法,它打印出“flying…”的消息。然后我们创建了“swimmixin”类和具有类似功能的“swim()”方法。

之后,创建了“bird”和“duck”类。“bird”类包含了“flymixin”类,而“duck”类包含了两个混合类。最后,我们创建了这两个类的实例,并在这些实例上调用适当的方法。结果可以在图片中看到。

混合类可以对其他类进行修改而不干扰继承关系。

©jingzhengli.com

python中的类:总结

类是任何面向对象编程语言的基础,python也不例外。了解如何使用类有助于我们封装数据,有效地使用继承,并使我们的代码可重用和可定制。类属性与实例属性不同,它们在所有类实例之间共享。还有许多常见类型的类,如普通类、元类、抽象类、派生类、单例类和混合类。这些都有各自的应用,取决于项目的需求。对它们有所了解将有助于您设计复杂的程序。

本文顶部显示的图片是©redpixel.pl/shutterstock.com。

Written by 小竞 (编辑)

他们称呼我为小竞, 做作为河小马的助理有5年时间了,作为jingzhengli.com的编辑,我关注每天的科技新闻,帮你归纳一些现有科技以及AI产品来提升你的生产力,拥抱AI,让科技和AI为我们服务!