零基础学 Python——类与对象(二)

类与对象:亦菲彦祖的有趣入门指南(第二部分)

亲爱的亦菲彦祖们,欢迎回到我们类与对象的奇妙世界!在第一部分中,我们已经了解了面向对象编程(OOP)的基本概念,学会了如何在Python中定义类、创建对象,以及掌握了self的奥秘。现在,是时候深入探索更高级的类特性,让我们的编程技能更上一层楼。准备好迎接更多编程乐趣了吗?让我们继续吧!

 

类的高级特性

在上一部分中,我们掌握了如何创建类和对象,并理解了self在方法中的作用。现在,让我们来探索类的高级特性,这些特性将使我们的类更加灵活和强大。

类属性

类属性是属于类本身的属性,而不是任何一个实例对象的属性。换句话说,类属性在所有实例之间共享,适用于那些不需要针对每个实例单独存储的数据。

比喻时间: 想象一下,所有的恐龙都有一个共同的祖先,这个祖先的信息可以作为类属性被所有恐龙共享。

示例

class Dinosaur:
    species = "恐龙"  # 类属性

    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age    # 实例属性

    def roar(self):
        print(f"{self.name} 大声吼叫,威风凛凛!")

使用类属性

# 创建两个Dinosaur对象
dino1 = Dinosaur("雷龙", 150)
dino2 = Dinosaur("迅猛龙", 80)

# 访问类属性
print(Dinosaur.species)  # 输出:恐龙

# 所有实例共享类属性
print(dino1.species)     # 输出:恐龙
print(dino2.species)     # 输出:恐龙

# 修改类属性
Dinosaur.species = "恐龙族"
print(dino1.species)     # 输出:恐龙族
print(dino2.species)     # 输出:恐龙族

类方法

类方法是与类相关联的方法,而不是与某个具体的实例相关联的方法。它们通常用于访问或修改类属性。

定义类方法

使用@classmethod装饰器,并将第一个参数命名为cls(代表类本身)。

示例

class Dinosaur:
    species = "恐龙"

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

    @classmethod
    def change_species(cls, new_species):
        cls.species = new_species
        print(f"恐龙种类已更新为:{cls.species}")

使用类方法

# 修改类属性通过类方法
Dinosaur.change_species("巨型恐龙")  # 输出:恐龙种类已更新为:巨型恐龙

# 所有实例共享更新后的类属性
dino1 = Dinosaur("雷龙", 150)
dino2 = Dinosaur("迅猛龙", 80)
print(dino1.species)  # 输出:巨型恐龙
print(dino2.species)  # 输出:巨型恐龙

静态方法

静态方法与类和实例都无关,它们只是类中的普通函数。使用@staticmethod装饰器定义。

使用场景: 当你需要在类中定义一个函数,但这个函数不需要访问类属性或实例属性时,使用静态方法。

示例

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b

    @staticmethod
    def subtract(a, b):
        return a - b

使用静态方法

# 通过类名调用静态方法
result1 = MathHelper.add(10, 5)
result2 = MathHelper.subtract(10, 5)
print(result1)  # 输出:15
print(result2)  # 输出:5

私有属性与方法

在编程中,封装是面向对象的重要特性之一。通过私有属性私有方法,我们可以隐藏类的内部实现细节,防止外部代码直接访问或修改这些内部数据。

私有属性

在Python中,通过在属性名前加双下划线__,可以将其设为私有属性。私有属性只能在类的内部访问,外部无法直接访问。

示例

class SecretAgent:
    def __init__(self, name, code_name):
        self.name = name            # 公有属性
        self.__code_name = code_name  # 私有属性

    def reveal_identity(self):
        print(f"真实姓名:{self.name}, 代号:{self.__code_name}")

使用私有属性

agent = SecretAgent("杰森·伯恩", "T-800")
agent.reveal_identity()  # 输出:真实姓名:杰森·伯恩, 代号:T-800

# 尝试访问私有属性
print(agent.__code_name)  # AttributeError: 'SecretAgent' object has no attribute '__code_name'

注意: 虽然Python通过名称重整(Name Mangling)机制使私有属性难以访问,但并不是绝对安全。以下方法仍可访问私有属性,但不推荐使用:

print(agent._SecretAgent__code_name)  # 输出:T-800

私有方法

同样地,通过在方法名前加双下划线__,可以将其设为私有方法。私有方法只能在类的内部调用,外部无法直接调用。

示例

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

    def greet(self):
        print(f"你好,我是{self.name}机器人。")
        self.__self_destruct()

    def __self_destruct(self):
        print(f"{self.name}即将自毁。启动倒计时3、2、1……")

使用私有方法

r2d2 = Robot("R2-D2")
r2d2.greet()
# 输出:
# 你好,我是R2-D2机器人。
# R2-D2即将自毁。启动倒计时3、2、1……

# 尝试调用私有方法
r2d2.__self_destruct()  # AttributeError: 'Robot' object has no attribute '__self_destruct'

特性(Property)

特性,又称计算属性,是一种通过方法来访问和修改属性的方式。使用@property装饰器,可以将方法伪装成属性,提供更灵活的属性访问和控制。

为什么使用特性?

  • 数据验证:在设置属性值时,可以进行验证或转换。
  • 封装:隐藏属性的内部实现细节,只暴露必要的接口。
  • 计算属性:根据其他属性动态计算值,而不是存储固定值。

使用@property创建特性

示例

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    @property
    def area(self):
        return self.width * self.height

    @property
    def perimeter(self):
        return 2 * (self.width + self.height)

    @perimeter.setter
    def perimeter(self, value):
        # 假设我们要调整宽度以达到新的周长,保持高度不变
        self.width = (value / 2) - self.height

使用特性

rect = Rectangle(5, 10)
print(rect.area)       # 输出:50
print(rect.perimeter)  # 输出:30

# 修改周长,调整宽度
rect.perimeter = 40
print(rect.width)      # 输出:15.0
print(rect.perimeter)  # 输出:40

解释

  • areaperimeter方法被@property装饰,使其可以像属性一样访问。
  • perimeter还定义了一个setter方法,允许我们通过设置perimeter属性来动态修改width

继承与多态简介

虽然本系列博客的第二部分已经非常丰富,但为了不让内容过于密集,我们将在未来的博客中深入探讨继承多态。简要介绍如下:

继承(Inheritance)

继承允许一个类(子类)继承另一个类(父类)的属性和方法,促进代码的复用和扩展。

示例

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

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print(f"{self.name} 说:汪汪!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} 说:喵喵!")

多态(Polymorphism)

多态允许不同的类以相同的方式调用方法,实现不同的行为。即使不同的对象调用相同的方法,也能表现出不同的反应。

示例

def make_animal_speak(animal):
    animal.speak()

dog = Dog("Buddy")
cat = Cat("Whiskers")

make_animal_speak(dog)  # 输出:Buddy 说:汪汪!
make_animal_speak(cat)  # 输出:Whiskers 说:喵喵!

趣味代码示例

让我们通过一个有趣的例子,综合运用类的高级特性,创建一个魔法学校的学生系统。

class Wizard:
    school = "魔法学校"  # 类属性
    total_wizards = 0     # 类属性,用于统计总人数

    def __init__(self, name, wand_type):
        self.name = name          # 实例属性
        self.wand_type = wand_type  # 实例属性
        Wizard.total_wizards += 1  # 更新类属性

    def cast_spell(self, spell):
        print(f"{self.name} 使用{self.wand_type}魔杖施放了{spell}!")

    @classmethod
    def wizard_count(cls):
        print(f"当前魔法学校的学生总数:{cls.total_wizards}")

    @staticmethod
    def school_info():
        print(f"{Wizard.school}致力于培养最优秀的巫师。")

    def __str__(self):
        return f"巫师:{self.name}, 魔杖类型:{self.wand_type}"

# 创建Wizard对象
harry = Wizard("哈利·波特", "柳木")
hermione = Wizard("赫敏·格兰杰", "紫檀木")

# 调用实例方法
harry.cast_spell("飞来咒")      # 输出:哈利·波特 使用柳木魔杖施放了飞来咒!
hermione.cast_spell("催动咒")  # 输出:赫敏·格兰杰 使用紫檀木魔杖施放了催动咒!

# 调用类方法
Wizard.wizard_count()  # 输出:当前魔法学校的学生总数:2

# 调用静态方法
Wizard.school_info()   # 输出:魔法学校致力于培养最优秀的巫师。

# 打印对象
print(harry)  # 输出:巫师:哈利·波特, 魔杖类型:柳木
print(hermione)  # 输出:巫师:赫敏·格兰杰, 魔杖类型:紫檀木

趣味点

  • 每当创建一个新的Wizard对象,total_wizards类属性自动更新,统计总人数。
  • 通过静态方法,展示学校的基本信息。
  • 重写__str__方法,使打印对象时更具可读性。

练习题:挑战你的编程智慧

亲爱的亦菲彦祖们,理论知识掌握得不错,现在是时候通过练习来巩固和扩展所学内容了!以下是几个小挑战,助你更上一层楼。

练习1:创建一个Car

  1. 定义类

    • 属性:
      • make(制造商)
      • model(型号)
      • year(年份)
      • mileage(里程)
    • 类属性:
      • total_cars(用于统计创建的汽车总数)
  2. 方法

    • drive(distance):增加里程。
    • car_count(类方法):打印当前汽车总数。
    • vehicle_info(静态方法):打印汽车的基本信息。
  3. 特殊方法

    • 重写__str__方法,返回汽车的详细信息。
  4. 创建对象并测试

    • 创建至少两个Car对象,调用各自的方法,验证功能。

提示

class Car:
    total_cars = 0  # 类属性

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.mileage = 0
        Car.total_cars += 1

    def drive(self, distance):
        self.mileage += distance
        print(f"{self.make} {self.model} 已行驶 {self.mileage} 公里。")

    @classmethod
    def car_count(cls):
        print(f"当前总共创建了 {cls.total_cars} 辆汽车。")

    @staticmethod
    def vehicle_info():
        print("汽车是现代社会中不可或缺的交通工具。")

    def __str__(self):
        return f"{self.year} {self.make} {self.model},里程:{self.mileage} 公里。"

练习2:扩展Wizard

  1. 添加私有属性

    • __magic_level(魔法等级)
  2. 添加方法

    • level_up():增加魔法等级。
    • get_magic_level()(特性):返回当前魔法等级。
  3. 使用特性

    • 使用@property装饰器,将get_magic_level转化为特性。
  4. 创建对象并测试

    • 创建一个Wizard对象,调用各方法,验证私有属性和特性的功能。

提示

class Wizard:
    school = "魔法学校"
    total_wizards = 0

    def __init__(self, name, wand_type):
        self.name = name
        self.wand_type = wand_type
        self.__magic_level = 1
        Wizard.total_wizards += 1

    def cast_spell(self, spell):
        print(f"{self.name} 使用{self.wand_type}魔杖施放了{spell}!")

    @classmethod
    def wizard_count(cls):
        print(f"当前魔法学校的学生总数:{cls.total_wizards}")

    @staticmethod
    def school_info():
        print(f"{Wizard.school}致力于培养最优秀的巫师。")

    @property
    def magic_level(self):
        return self.__magic_level

    def level_up(self):
        self.__magic_level += 1
        print(f"{self.name} 的魔法等级提升至 {self.__magic_level}!")

    def __str__(self):
        return f"巫师:{self.name}, 魔杖类型:{self.wand_type}, 魔法等级:{self.__magic_level}"

练习3:探索继承

  1. 定义父类Animal

    • 属性:name
    • 方法:speak()
  2. 定义子类DogCat,继承自Animal

    • Dogspeak()方法输出:“{name} 说:汪汪!”
    • Catspeak()方法输出:“{name} 说:喵喵!”
  3. 创建对象并测试

    • 创建DogCat对象,调用各自的speak()方法,验证多态性。

提示

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

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print(f"{self.name} 说:汪汪!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} 说:喵喵!")

# 创建对象
dog = Dog("Buddy")
cat = Cat("Whiskers")

# 调用方法
dog.speak()  # 输出:Buddy 说:汪汪!
cat.speak()  # 输出:Whiskers 说:喵喵!

总结:成为类与对象的高手

恭喜你,亦菲彦祖们!通过这两部分的学习,你们已经从零开始,系统地掌握了Python中类与对象的核心知识。从基本的类定义和对象创建,到高级特性如类属性、类方法、静态方法,再到封装的私有属性与方法,以及特性的应用,你们已经为构建复杂且高效的程序打下了坚实的基础。

回顾要点

  • 类(Class):对象的蓝图,定义了对象的属性和方法。
  • 对象(Object):类的实例,拥有独立的属性值和行为。
  • __init__方法:初始化对象属性,确保对象在创建时具备必要的状态。
  • 类属性:属于类本身,所有实例共享的属性。
  • 类方法:与类相关联的方法,通常用于操作类属性。
  • 静态方法:独立于类和实例的方法,适用于工具函数。
  • 私有属性与方法:封装类内部的实现细节,保护数据不被外部直接访问。
  • 特性(Property):通过方法控制属性的访问和修改,实现数据验证和动态计算。
  • 继承与多态:促进代码复用和灵活性,使得不同类的对象能够以统一的方式交互。

展望未来

掌握了类与对象的高级特性后,你们已经具备了开发复杂应用的能力。接下来的学习中,我们将深入探讨继承多态,并结合实际案例,进一步提升编程技能。同时,了解如何设计良好的类结构、优化代码的可读性与维护性,也是成为优秀开发者的重要一步。

小贴士

  • 多实践:理论知识需要通过实践来巩固,多写代码、多调试。
  • 阅读源码:学习优秀开源项目的类设计,理解不同的设计模式。
  • 持续学习:编程世界日新月异,保持学习的热情,不断探索新的知识领域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨胜增

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值