类和方法的概念及实例
类 (Class):类是对具有相同属性和方法的对象集合的抽象描述。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
方法:类中定义的函数。
构造方法 __init__():这是一个特殊的方法,会在类实例化时自动调用。
实例变量:类中用变量表示的属性,这种变量称为实例变量,是用 self
修饰的变量。
实例化:创建一个类的实例,即创建一个类的具体对象。
继承:一个派生类 (derived class) 继承基类 (base class) 的属性和方法。继承允许将派生类对象作为基类对象对待。
为了便于理解,每种类型的示例都包括从简单到复杂的三个示例。
1. Python类:class
Python中的class
相当于一个包含多个函数的集合。如果在AnimalClass
类中有一个方法make_sound
,当我们需要调用它时,必须使用AnimalClass.make_sound
来调用,即在调用时需要带上类名。
简单示例
在这个简单示例中,我们定义了一个名为AnimalClass
的类,它有一个类变量num_legs
和一个方法make_sound
。
# AnimalClass 类
class AnimalClass:
"""一个简单的类实例"""
num_legs = 4
def make_sound(self):
return 'generic sound'
# 实例化类
animal_instance = AnimalClass()
# 访问类的属性和方法
print("AnimalClass 类的属性 num_legs 为:", animal_instance.num_legs)
print("AnimalClass 类的方法 make_sound 输出为:", animal_instance.make_sound())
中等难度示例
在这个示例中,我们定义了一个名为Car
的类,它有一个构造方法来初始化实例变量brand
和model
,并且有一个方法display_info
来显示车辆信息。
# Car 类
class Car:
"""一个简单的类实例"""
def __init__(self, brand, model):
self.brand = brand
self.model = model
def display_info(self):
return f"Car brand: {self.brand}, model: {self.model}"
# 实例化类
car_instance = Car("Toyota", "Corolla")
# 访问类的方法
print(car_instance.display_info())
复杂示例
在这个复杂示例中,我们定义了一个名为NeuralNetwork
的类,它继承了nn.Module
,用于构建一个简单的神经网络。
# NeuralNetwork 类
import torch
import torch.nn as nn
class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork, self).__init__()
self.layer1 = nn.Linear(10, 50)
self.layer2 = nn.Linear(50, 1)
def forward(self, x):
x = torch.relu(self.layer1(x))
x = self.layer2(x)
return x
# 实例化类
model = NeuralNetwork()
print(model)
2. 类的构造方法 __init__()
构造方法 __init__() 是类与外界的联系方法,当创建类的实例时,会自动调用这个方法。
简单示例
在这个简单示例中,我们定义了一个名为Point
的类,它有一个构造方法来初始化实例变量x_coord
和y_coord
。
class Point:
def __init__(self, x, y):
self.x_coord = x
self.y_coord = y
p = Point(2.5, 4.0)
print(p.x_coord, p.y_coord) # 输出结果:2.5 4.0
中等难度示例
在这个示例中,我们定义了一个名为Person
的类,它有一个构造方法来初始化实例变量name
和age
,并且有一个方法greet
来返回一个问候字符串。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
p = Person("Alice", 30)
print(p.greet())
复杂示例
在这个复杂示例中,我们定义了一个名为Dataset
的类,用于处理数据和标签的集合。它实现了两个特殊方法:__len__
返回数据的长度,__getitem__
返回指定索引的数据和标签。
class Dataset:
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx], self.labels[idx]
data = [torch.randn(10) for _ in range(100)]
labels = [torch.randint(0, 2, (1,)) for _ in range(100)]
dataset = Dataset(data, labels)
print(f"Dataset length: {len(dataset)}")
print(f"First item: {dataset[0]}")
3. 类中方法的参数 self
类方法的第一个参数必须是 self
,它代表类的实例。
简单示例
在这个简单示例中,我们定义了一个名为Dog
的类,它有一个构造方法来初始化实例变量name
,并且有一个方法bark
来打印狗叫声。
# 类定义
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name} says woof!")
# 实例化类
dog_instance = Dog("Buddy")
dog_instance.bark()
中等难度示例
在这个示例中,我们定义了一个名为Rectangle
的类,它有一个构造方法来初始化实例变量width
和height
,并且有两个方法area
和perimeter
分别计算矩形的面积和周长。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
rect = Rectangle(3, 4)
print(f"Area: {rect.area()}, Perimeter: {rect.perimeter()}")
复杂示例
在这个复杂示例中,我们定义了一个名为LSTMNetwork
的类,它继承了nn.Module
,用于构建一个简单的LSTM神经网络。
class LSTMNetwork(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(LSTMNetwork, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.lstm(x)
out = self.fc(out[:, -1, :])
return out
# 实例化类
lstm_model = LSTMNetwork(input_size=10, hidden_size=20, output_size=1)
print(lstm_model)
4. 继承
一个类可以继承另一个类的属性和方法,这称为继承。
简单示例
在这个简单示例中,我们定义了一个名为Animal
的基类和一个名为Cat
的派生类。Cat
类继承了Animal
类的属性和方法,并且重写了make_sound
方法。
class Animal:
def __init__(self, species):
self.species = species
def make_sound(self):
print("Some generic sound")
class Cat(Animal):
def __init__(self, species, name):
super().__init__(species)
self.name = name
def make_sound(self):
print(f"{self.name} says meow")
cat_instance = Cat("Feline", "Whiskers")
cat_instance.make_sound()
中等难度示例
在这个示例中,我们定义了一个名为Employee
的基类和一个名为Manager
的派生类。Manager
类继承了Employee
类的属性和方法,并且重写了work
方法。
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def work(self):
print(f"{self.name} is working")
class Manager(Employee):
def __init__(self, name, salary, department):
super().__init__(name, salary)
self.department = department
def work(self):
print(f"{self.name} is managing the {self.department} department")
manager_instance = Manager("Alice", 90000, "HR")
manager_instance.work()
复杂示例
在这个复杂示例中,我们定义了一个名为BaseModel
的基类和一个
名为CNNModel
的派生类。CNNModel
类继承了BaseModel
类的属性和方法,并且实现了forward
方法。
class BaseModel(nn.Module):
def __init__(self):
super(BaseModel, self).__init__()
def forward(self, x):
raise NotImplementedError("Subclasses should implement this!")
class CNNModel(BaseModel):
def __init__(self, num_classes):
super(CNNModel, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.fc1 = nn.Linear(64*7*7, 128)
self.fc2 = nn.Linear(128, num_classes)
self.dropout = nn.Dropout(0.5)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.max_pool2d(x, kernel_size=2, stride=2)
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, kernel_size=2, stride=2)
x = x.view(-1, 64*7*7)
x = F.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
# 实例化类
cnn_model = CNNModel(num_classes=10)
print(cnn_model)
5. 方法重写
子类可以重写父类的方法。
简单示例
在这个简单示例中,我们定义了一个名为Animal
的基类和一个名为Dog
的派生类。Dog
类重写了Animal
类的sound
方法。
class Animal:
def sound(self):
print('动物的声音')
class Dog(Animal):
def sound(self):
print('狗叫声')
dog_instance = Dog()
dog_instance.sound()
super(Dog, dog_instance).sound()
中等难度示例
在这个示例中,我们定义了一个名为Writer
的基类和一个名为Blogger
的派生类。Blogger
类重写了Writer
类的write
方法。
class Writer:
def write(self):
print("Writing generic content")
class Blogger(Writer):
def write(self):
print("Writing blog content")
blogger_instance = Blogger()
blogger_instance.write()
super(Blogger, blogger_instance).write()
复杂示例
在这个复杂示例中,我们定义了一个名为BaseOptimizer
的基类和一个名为SGDOptimizer
的派生类。SGDOptimizer
类重写了BaseOptimizer
类的step
方法。
class BaseOptimizer:
def __init__(self, lr):
self.lr = lr
def step(self):
raise NotImplementedError("Subclasses should implement this!")
class SGDOptimizer(BaseOptimizer):
def __init__(self, lr, momentum):
super().__init__(lr)
self.momentum = momentum
def step(self):
print(f"Performing SGD step with lr={self.lr} and momentum={self.momentum}")
# 实例化类
optimizer = SGDOptimizer(lr=0.01, momentum=0.9)
optimizer.step()