超详细!Python 类 Class--详细整理

本文详细介绍了Python的类,包括类的创建和实例化、属性(实例属性、类属性、公有属性和私有属性)、方法(实例方法、类方法和静态方法)以及继承、多态等核心概念。文章通过实例展示了如何定义和使用类、属性和方法,并探讨了类的继承和多态性在Python编程中的应用。此外,还讨论了如何通过`__init__`构造函数初始化实例,以及如何通过`super()`函数调用父类方法。最后,文章强调了多态在提高代码灵活性和可扩展性方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 类

在这里插入图片描述

1 类的创建和类的实例

Python 是一种面向对象的编程语言,其中类是非常重要的概念。

是一种用户定义的数据类型,它代表着一类具有相同属性和方法的对象的集合。

实例则是类的具体实现,是类的一个个体,可以使用类定义的属性和方法。

  1. 定义类:使用关键字 class
  2. 创建一个类的对象:可以通过类名后面加括号来创建一个实例
  • __init__() 作为类的构造方法,用来初始化类的实例,
  • self 表示类的实例本身。
    • self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定使用 self
  • 其他方法则按照正常函数的形式定义。
  • 类可以定义属性和方法,属性是类的数据成员,方法是类的函数成员。
  • 类的方法与普通的函数只有一个特别的区别:它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
class Dog:
    def __init__(self, name, breed, age):
        self.name = name
        self.breed = breed
        self.age = age

my_dog = Dog('Buddy', 'Golden Retriever', 6)

上面的代码中,“Dog”类表示狗类,它包含名字、品种和年龄这三个属性。

创建了一个 “my_dog” 的实例,该实例有名为 “Buddy” 的名字、品种为 “Golden Retriever”、年龄为 6 岁。

此时,my_dog 变量就代表了一个狗类的实例,可以通过访问它的属性来获取相应的信息,例如:

print(my_dog.age)

这将打印出 6。同时,也可以使用对象的方法来修改属性或进行其他操作:

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

    def bark(self):
        print('Woof woof!')

my_dog = Dog('Buddy', 'Golden Retriever', 6)

my_dog.bark()  # 输出 “Woof woof!”

2 类的属性

在 Python 中,类的属性可以被理解为类的变量。

Python 的公有属性、私有属性以及实例属性、静态属性之间是存在关联的,具体关系如下:

  • 公有属性:指没有加前缀双下划线__的属性,可以在类内外被访问,也可以被继承和重写。

  • 私有属性:指加了前缀双下划线__的属性,只能在类内被访问和修改,而在类外部无法访问或修改。

  • 实例属性:指定义在 __init__ 方法中,以 self.属性名 的形式定义的属性,每个实例都独立拥有一个自己的实例属性,它们随实例创建和销毁。

  • 静态属性:指在类下直接定义的属性,可以使用类名直接访问,它们是类的属性,每个实例都共享一个静态属性。

公有属性和私有属性是属于对象或类中的实例属性或静态属性的一种访问方式,

也就是说,公有属性和私有属性可以同时作为实例属性和静态属性存在。

对于 Python 中的公有属性和实例属性的关系,可以通过实例的 self.属性名 来访问和修改;

而对于 Python 中的私有属性,则需要在属性名前面加上双下划线"__",才能被认定为私有属性,无法通过实例调用,只能通过类内部的方法进行访问和修改。对于静态属性,则是直接定义在类下,可以使用类名进行访问和修改。

2.1 实例属性和类属性

类的属性有两种类型:实例属性和类属性。

类型 定义 特点
实例属性 类的实例的属性 各个实例相互之间不产生影响
静态属性/类属性 类本身的属性 类的所有实例都共享一份类属性,各个实例相互之间会产生影响
属性 实例属性 静态属性
定义方式和作用 定义在实例方法中,仅对当前实例有效 定义在类中,对所有实例共享同一份
访问方式 通过实例进行访问 通过类名进行访问
访问时用的是哪个对象属性 实例属性值 只有一个静态属性值,共用同一个
生命周期 随着实例的创建和销毁而创建和销毁 随着类的创建和销毁而创建和销毁
作用域 实例内部作用域内 类的内部作用域内
示例 self.name = '张三' (在 init 中) name = '李四' (在类中)

2.1.1 实例属性

实例属性是指属于某个对象的属性,每个对象都有自己独立的实例属性,相互之间不会产生影响。

实例属性的赋值一般在类的初始化方法 __init__ 中进行,也可以在对象创建之后通过赋值来添加实例属性。

例如,我们定义一个人类 Person,可以在初始化方法中定义实例属性 nameage,如下所示:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

2.1.2 静态属性/类属性

  • 类属性是指属于整个类的属性,所有对象共享一份类属性,相互之间会产生影响。
  • 类属性一般在类的定义中直接定义,也可以在类的其他方法中添加。
  • 类的属性是反映类内部状态的变量,可以在类的定义中定义和修改,也可以在类的其他方法中访问和使用。
  • 理解好类的属性对于深入理解 Python 面向对象编程非常重要。

例如,我们为人类 Person 添加一个类属性 species,表示人类的种类,定义如下:

class Person:
    species = 'human'  # 定义类属性

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_species(self):  # 定义实例方法
        return self.species

  1. 在类属性的访问和修改上,可以通过类名或对象名来访问。

例如,我们可以通过 Person.species 来访问类属性,也可以通过 person1.species 来访问对象 person1 的类属性。

  1. 类属性的修改同样可以通过类名或对象名来实现。

如果通过对象名修改类属性,则会创建一个同名的实例属性,该实例属性会覆盖掉类属性的值,不会改变类属性的值。

例如,我们修改 person1.species 的值为 'homo erectus',则会创建一个实例属性 species,它的值为 'homo erectus',但是不会改变类属性 Person.species 的值。

2.2 公有属性和私有属性

在 Python 中,类的属性(或者成员变量)也可以分为公有属性和私有属性。

属性类型 声明方式 外部访问方式 内部访问方式
公有属性 未加任何修饰符 直接访问 直接访问
私有属性 在属性名前面加双下划线 __ 不能直接访问,可以通过访问方法间接访问 可以直接访问

2.2.1 公有属性

公有属性是指可以从类的外部直接访问和修改的属性,一般在类的构造方法中用 self 关键字来定义,例如:

class Student:
    def __init__(self, name, age):
        self.name = name  # 公有属性
        self.age = age  # 公有属性

在这个例子中,nameage 都是公有属性,我们可以通过实例对象直接访问和修改它们的值:

s = Student('Lucy', 20)
print(s.name)  # 'Lucy'
s.age = 21
print(s.age)  # 21

2.2.2 私有属性

私有属性是指不能从类的外部直接访问和修改的属性。在 Python 中,可以通过在属性名前面加上双下划线 __ 来定义私有属性,例如:

class Student:
    def __init__(self, name, age):
        self.__name = name  # 私有属性
        self.__age = age  # 私有属性

在这个例子中,__name__age 都是私有属性,我们无法直接访问和修改它们的值:

s = Student('Lucy', 20)
print(s.__name)  # AttributeError: 'Student' object has no attribute '__name'
s.__age = 21  # AttributeError: 'Student' object has no attribute '__age'

这是因为 Python 解释器会自动将属性名 __name__age 替换成 _Student__name_Student__age,从而防止属性被意外访问和修改。

虽然无法直接访问和修改私有属性,但是我们可以通过类内部定义的方法来访问和修改它们的值,例如:

<think>好的,我需要帮助用户找到用Python实现多层感知机(MLP)对Fashion-MNIST数据集进行分的代码示例,并且用户提到了TensorFlow、PyTorch和Keras这三个框架。首先,我得回忆一下这些框架的基本用法以及它们处理数据集的方式。 用户的问题涉及三个不同的库,所以我需要分别考虑每个框架的实现步骤。首先,我应该检查用户提供的引用内容,看是否有相关的示例或提示。根据引用[1],Keras实现MNIST手写识别的多层感知机已经有过介绍,可能代码结构可以直接参考,不过用户这次需要的是Fashion-MNIST数据集,这和MNIST结构似,但内容不同。引用[3]提到了PyTorch在FashionMNIST上的应用,而引用[4]提到了TensorFlow和Keras处理鸢尾花数据集,这可能对结构有帮助。 首先,我需要确保每个框架的示例代码是正确的,并且符合最佳实践。例如,在Keras中,数据预处理可能需要先加载Fashion-MNIST数据集,然后归一化,并展平图像数据。然后构建模型,添加全连接层、激活函数,编译模型,最后训练和评估。 对于PyTorch部分,需要处理数据加载,定义模型,使用DataLoader,设置损失函数和优化器,训练循环和评估。引用[3]提到PyTorch在CPU使用上更高效,这点可以适当提及。 TensorFlow的实现可能与Keras似,因为Keras现在集成在TensorFlow中,但可能需要使用tf.data来处理数据集,或者直接使用内置的Fashion-MNIST数据集。 接下来,我需要确保每个框架的代码示例正确无误,没有语法错误,并且能够直接运行。例如,在Keras中,可能需要使用Flatten层将图像从二维转换为一维,而在PyTorch中,需要在模型的前向传播中进行展平操作。 同时,需要注意Fashion-MNIST的输入形状是28x28的灰度图像,所以输入层的大小应为784(28*28)。输出层是10个别,使用Softmax激活函数。中间层可能需要使用ReLU激活函数,并且可能需要添加Dropout层来防止过拟合,但用户没有特别提到,所以基础模型可能不需要这些。 还需要验证各个框架中如何加载Fashion-MNIST数据集。例如,Keras和TensorFlow可能直接有内置的函数,而PyTorch可能需要通过torchvision.datasets.FashionMNIST来加载。 在编写代码时,需要注意变量命名的一致性,比如训练周期数、批量大小等参数是否统一,或者根据框架的不同进行调整。例如,Keras使用model.fit,而PyTorch需要手动编写训练循环。 此外,评估模型时,Keras和TensorFlow可能直接使用model.evaluate,而PyTorch则需要手动计算准确率,通过遍历测试数据集,累计正确预测的数量。 最后,生成相关问题需要考虑用户可能感兴趣的后续问题,比如性能优化、不同框架的比较、超参数调整等,基于引用中提到的内容,比如引用[2]关于移动端部署,引用[3]关于框架比较,引用[4]关于其他数据集的应用。 现在,我需要将上述思考整理成三个框架的代码示例,并确保每个步骤清晰,符合用户的要求。同时,添加相关问题,帮助用户进一步探索。</think>### 使用Python实现多层感知机(MLP)对Fashion-MNIST分 以下是基于Keras、PyTorch和TensorFlow框架的实现方法及代码示例: --- ### **1. 使用Keras实现** Keras提供了简洁的API,适合快速搭建模型。 ```python import numpy as np from tensorflow.keras.datasets import fashion_mnist from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Flatten from tensorflow.keras.utils import to_categorical # 加载数据集 (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data() # 数据预处理 train_images = train_images.astype('float32') / 255 test_images = test_images.astype('float32') / 255 train_labels = to_categorical(train_labels) # 标签独热编码 test_labels = to_categorical(test_labels) # 构建模型 model = Sequential([ Flatten(input_shape=(28, 28)), # 展平图像 Dense(128, activation='relu'), # 隐藏层 Dense(10, activation='softmax') # 输出层 ]) # 编译与训练 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=10, batch_size=64, validation_split=0.2) # 评估模型 test_loss, test_acc = model.evaluate(test_images, test_labels) print(f"Test accuracy: {test_acc:.4f}") ``` **要点**: - 使用`Flatten`层将28x28图像转换为784维向量[^1]。 - 输出层采用Softmax激活函数实现多分--- ### **2. 使用PyTorch实现** PyTorch灵活性更高,适合自定义模型结构。 ```python import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader # 数据加载与预处理 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]) train_set = datasets.FashionMNIST('data', download=True, train=True, transform=transform) test_set = datasets.FashionMNIST('data', download=True, train=False, transform=transform) train_loader = DataLoader(train_set, batch_size=64, shuffle=True) test_loader = DataLoader(test_set, batch_size=64, shuffle=False) # 定义模型 class MLP(nn.Module): def __init__(self): super().__init__() self.layers = nn.Sequential( nn.Flatten(), # 展平图像 nn.Linear(784, 128), # 输入层到隐藏层 nn.ReLU(), # 激活函数 nn.Linear(128, 10) # 输出层 ) def forward(self, x): return self.layers(x) model = MLP() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters()) # 训练 for epoch in range(10): for images, labels in train_loader: outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() # 评估 correct = 0 total = 0 with torch.no_grad(): for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f"Test accuracy: {correct / total:.4f}") ``` **要点**: - 使用`nn.Flatten`处理输入数据,无需手动调整维度[^3]。 - PyTorch的`DataLoader`支持批量加载和随机打乱。 --- ### **3. 使用TensorFlow实现** TensorFlow提供完整的生态系统支持。 ```python import tensorflow as tf from tensorflow.keras.datasets import fashion_mnist # 加载数据 (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data() # 预处理 train_images = train_images.reshape(-1, 784).astype('float32') / 255 test_images = test_images.reshape(-1, 784).astype('float32') / 255 train_labels = tf.keras.utils.to_categorical(train_labels) test_labels = tf.keras.utils.to_categorical(test_labels) # 定义模型 model = tf.keras.Sequential([ tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)), tf.keras.layers.Dense(10, activation='softmax') ]) # 编译与训练 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=10, batch_size=64, validation_split=0.2) # 评估 test_loss, test_acc = model.evaluate(test_images, test_labels) print(f"Test accuracy: {test_acc:.4f}") ``` **要点**: - 直接使用`reshape`将图像展平为一维向量[^4]。 - TensorFlow与Keras无缝集成,API风格一致。 --- ### **性能优化建议** 1. **增加隐藏层**:尝试添加更多隐藏层(如256、512神经元)以提升模型容量。 2. **正则化**:使用Dropout层(如`Dropout(0.5)`)防止过拟合。 3. **学习率调整**:通过`ReduceLROnPlateau`动态调整学习率。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值