百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

简单的python-核心篇-面向对象编程

itomcoil 2025-10-23 03:55 1 浏览

在Python中,类本身也是对象,这被称为"元类"。这种设计让Python的面向对象编程具有极大的灵活性。

class MyClass:
    """一个简单的类"""
    class_var = "我是类变量"
    
    def __init__(self, value):
        self.instance_var = value
    
    def instance_method(self):
        return f"实例方法: {self.instance_var}"
    
    @classmethod
    def class_method(cls):
        return f"类方法: {cls.class_var}"
    
    @staticmethod
    def static_method():
        return "静态方法"

# 类本身也是对象
print(f"类对象: {MyClass}")
print(f"类的类型: {type(MyClass)}")
print(f"类的基类: {MyClass.__bases__}")

# 创建实例
obj = MyClass("实例值")
print(obj.instance_method())
print(MyClass.class_method())
print(MyClass.static_method())

类的构造与析构

1. 特殊方法(魔术方法)

class Person:
    def __init__(self, name, age):
        """构造方法"""
        self.name = name
        self.age = age
        print(f"创建了Person实例: {self.name}")
    
    def __del__(self):
        """析构方法"""
        print(f"销毁了Person实例: {self.name}")
    
    def __str__(self):
        """字符串表示"""
        return f"Person({self.name}, {self.age})"
    
    def __repr__(self):
        """开发者表示"""
        return f"Person(name='{self.name}', age={self.age})"
    
    def __len__(self):
        """长度"""
        return len(self.name)
    
    def __bool__(self):
        """布尔值"""
        return self.age > 0

# 测试特殊方法
person = Person("Alice", 25)
print(str(person))    # Person(Alice, 25)
print(repr(person))   # Person(name='Alice', age=25)
print(len(person))    # 5
print(bool(person))   # True

# 析构方法会在对象被垃圾回收时调用
del person

2. 属性访问控制

class BankAccount:
    def __init__(self, initial_balance=0):
        self._balance = initial_balance  # 受保护的属性
        self.__account_id = id(self)     # 私有属性
    
    @property
    def balance(self):
        """余额属性"""
        return self._balance
    
    @balance.setter
    def balance(self, value):
        """设置余额"""
        if value < 0:
            raise ValueError("余额不能为负数")
        self._balance = value
    
    @property
    def account_id(self):
        """账户ID(只读)"""
        return self.__account_id
    
    def deposit(self, amount):
        """存款"""
        if amount <= 0:
            raise ValueError("存款金额必须大于0")
        self._balance += amount
        return self._balance
    
    def withdraw(self, amount):
        """取款"""
        if amount <= 0:
            raise ValueError("取款金额必须大于0")
        if amount > self._balance:
            raise ValueError("余额不足")
        self._balance -= amount
        return self._balance

# 使用属性
account = BankAccount(1000)
print(f"余额: {account.balance}")
print(f"账户ID: {account.account_id}")

account.deposit(500)
print(f"存款后余额: {account.balance}")

account.withdraw(200)
print(f"取款后余额: {account.balance}")

# account.balance = -100  # ValueError: 余额不能为负数
# account.account_id = 123  # AttributeError: can't set attribute

继承的艺术

1. 单继承

class Animal:
    """动物基类"""
    def __init__(self, name, species):
        self.name = name
        self.species = species
    
    def make_sound(self):
        return "Some generic animal sound"
    
    def move(self):
        return f"{self.name} is moving"
    
    def __str__(self):
        return f"{self.species}: {self.name}"

class Dog(Animal):
    """狗类"""
    def __init__(self, name, breed):
        super().__init__(name, "Dog")  # 调用父类构造方法
        self.breed = breed
    
    def make_sound(self):
        return "Woof!"
    
    def fetch(self):
        return f"{self.name} is fetching"

class Cat(Animal):
    """猫类"""
    def __init__(self, name, color):
        super().__init__(name, "Cat")
        self.color = color
    
    def make_sound(self):
        return "Meow!"
    
    def climb(self):
        return f"{self.name} is climbing"

# 使用继承
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Whiskers", "Orange")

print(dog.make_sound())  # Woof!
print(cat.make_sound())  # Meow!
print(dog.fetch())       # Buddy is fetching
print(cat.climb())       # Whiskers is climbing

# 多态性
animals = [dog, cat]
for animal in animals:
    print(f"{animal}: {animal.make_sound()}")

2. 多重继承

class Flyable:
    """可飞行接口"""
    def fly(self):
        return "Flying through the air"

class Swimmable:
    """可游泳接口"""
    def swim(self):
        return "Swimming in water"

class Duck(Animal, Flyable, Swimmable):
    """鸭子类 - 多重继承"""
    def __init__(self, name):
        super().__init__(name, "Duck")
    
    def make_sound(self):
        return "Quack!"
    
    def move(self):
        return f"{self.name} is waddling"

# 使用多重继承
duck = Duck("Donald")
print(duck.make_sound())  # Quack!
print(duck.fly())         # Flying through the air
print(duck.swim())        # Swimming in water
print(duck.move())        # Donald is waddling

# 方法解析顺序(MRO)
print(Duck.__mro__)
# (<class '__main__.Duck'>, <class '__main__.Animal'>, 
#  <class '__main__.Flyable'>, <class '__main__.Swimmable'>, <class 'object'>)

3. 钻石问题与super()

class A:
    def method(self):
        return "A"

class B(A):
    def method(self):
        return "B -> " + super().method()

class C(A):
    def method(self):
        return "C -> " + super().method()

class D(B, C):
    def method(self):
        return "D -> " + super().method()

# 测试钻石问题
d = D()
print(d.method())  # D -> B -> C -> A
print(D.__mro__)   # (<class '__main__.D'>, <class '__main__.B'>, 
                   #  <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

# 使用super()的好处
class Base:
    def __init__(self, value):
        self.value = value
        print(f"Base初始化: {value}")

class Child1(Base):
    def __init__(self, value, extra1):
        super().__init__(value)
        self.extra1 = extra1
        print(f"Child1初始化: {extra1}")

class Child2(Base):
    def __init__(self, value, extra2):
        super().__init__(value)
        self.extra2 = extra2
        print(f"Child2初始化: {extra2}")

class GrandChild(Child1, Child2):
    def __init__(self, value, extra1, extra2):
        super().__init__(value, extra1, extra2)
        print("GrandChild初始化完成")

# 测试super()链式调用
gc = GrandChild(10, "extra1", "extra2")

抽象基类与接口

1. 抽象基类

from abc import ABC, abstractmethod

class Shape(ABC):
    """抽象形状类"""
    def __init__(self, name):
        self.name = name
    
    @abstractmethod
    def area(self):
        """计算面积"""
        pass
    
    @abstractmethod
    def perimeter(self):
        """计算周长"""
        pass
    
    def describe(self):
        """描述形状"""
        return f"{self.name}: 面积={self.area():.2f}, 周长={self.perimeter():.2f}"

class Rectangle(Shape):
    """矩形类"""
    def __init__(self, width, height):
        super().__init__("矩形")
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

class Circle(Shape):
    """圆形类"""
    def __init__(self, radius):
        super().__init__("圆形")
        self.radius = radius
    
    def area(self):
        import math
        return math.pi * self.radius ** 2
    
    def perimeter(self):
        import math
        return 2 * math.pi * self.radius

# 使用抽象基类
shapes = [
    Rectangle(5, 3),
    Circle(4),
    Rectangle(2, 8)
]

for shape in shapes:
    print(shape.describe())

# 不能直接实例化抽象类
# shape = Shape("抽象形状")  # TypeError: Can't instantiate abstract class Shape

2. 协议(鸭子类型)

from typing import Protocol

class Drawable(Protocol):
    """可绘制协议"""
    def draw(self) -> str:
        ...

class Paintable(Protocol):
    """可绘制协议"""
    def paint(self) -> str:
        ...

class Canvas:
    """画布类"""
    def draw(self):
        return "在画布上绘制"
    
    def paint(self):
        return "在画布上绘画"

class Paper:
    """纸张类"""
    def draw(self):
        return "在纸上绘制"

# 鸭子类型:如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子
def draw_something(drawable: Drawable):
    return drawable.draw()

def paint_something(paintable: Paintable):
    return paintable.paint()

# 使用协议
canvas = Canvas()
paper = Paper()

print(draw_something(canvas))  # 在画布上绘制
print(draw_something(paper))   # 在纸上绘制
print(paint_something(canvas)) # 在画布上绘画
# print(paint_something(paper))  # 错误:Paper没有paint方法

类装饰器与元类

1. 类装饰器

def singleton(cls):
    """单例装饰器"""
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Database:
    def __init__(self):
        self.connection = "数据库连接"
        print("创建数据库连接")

# 测试单例
db1 = Database()
db2 = Database()
print(db1 is db2)  # True

def add_method(method_name, method):
    """添加方法装饰器"""
    def decorator(cls):
        setattr(cls, method_name, method)
        return cls
    return decorator

@add_method("greet", lambda self: f"Hello from {self.__class__.__name__}")
class MyClass:
    pass

obj = MyClass()
print(obj.greet())  # Hello from MyClass

2. 元类

class SingletonMeta(type):
    """单例元类"""
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Logger(metaclass=SingletonMeta):
    def __init__(self):
        self.logs = []
    
    def log(self, message):
        self.logs.append(message)
        print(f"日志: {message}")

# 测试单例元类
logger1 = Logger()
logger2 = Logger()
print(logger1 is logger2)  # True

logger1.log("第一条日志")
logger2.log("第二条日志")
print(f"日志数量: {len(logger1.logs)}")  # 2

class AutoPropertyMeta(type):
    """自动属性元类"""
    def __new__(cls, name, bases, attrs):
        # 为所有以'_'开头的属性创建property
        for key, value in attrs.items():
            if key.startswith('_') and not key.startswith('__'):
                prop_name = key[1:]  # 去掉下划线
                attrs[prop_name] = property(
                    lambda self, k=key: getattr(self, k),
                    lambda self, val, k=key: setattr(self, k, val)
                )
        return super().__new__(cls, name, bases, attrs)

class AutoProperty(metaclass=AutoPropertyMeta):
    def __init__(self):
        self._value = 0

# 测试自动属性
obj = AutoProperty()
obj.value = 42
print(obj.value)  # 42

设计模式在Python中的实现

1. 工厂模式

class AnimalFactory:
    """动物工厂"""
    @staticmethod
    def create_animal(animal_type, name, **kwargs):
        if animal_type == "dog":
            return Dog(name, kwargs.get("breed", "Unknown"))
        elif animal_type == "cat":
            return Cat(name, kwargs.get("color", "Unknown"))
        elif animal_type == "duck":
            return Duck(name)
        else:
            raise ValueError(f"未知的动物类型: {animal_type}")

# 使用工厂
animals = [
    AnimalFactory.create_animal("dog", "Buddy", breed="Golden Retriever"),
    AnimalFactory.create_animal("cat", "Whiskers", color="Orange"),
    AnimalFactory.create_animal("duck", "Donald")
]

for animal in animals:
    print(f"{animal}: {animal.make_sound()}")

2. 观察者模式

class Subject:
    """主题类"""
    def __init__(self):
        self._observers = []
    
    def attach(self, observer):
        if observer not in self._observers:
            self._observers.append(observer)
    
    def detach(self, observer):
        if observer in self._observers:
            self._observers.remove(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

class Observer:
    """观察者基类"""
    def update(self, message):
        raise NotImplementedError

class EmailNotifier(Observer):
    """邮件通知器"""
    def update(self, message):
        print(f"邮件通知: {message}")

class SMSNotifier(Observer):
    """短信通知器"""
    def update(self, message):
        print(f"短信通知: {message}")

class NewsAgency(Subject):
    """新闻社"""
    def __init__(self):
        super().__init__()
        self.news = []
    
    def publish_news(self, news):
        self.news.append(news)
        self.notify(news)

# 使用观察者模式
news_agency = NewsAgency()
email_notifier = EmailNotifier()
sms_notifier = SMSNotifier()

news_agency.attach(email_notifier)
news_agency.attach(sms_notifier)

news_agency.publish_news("重要新闻:Python 3.12发布!")

3. 策略模式

class PaymentStrategy:
    """支付策略接口"""
    def pay(self, amount):
        raise NotImplementedError

class CreditCardPayment(PaymentStrategy):
    """信用卡支付"""
    def __init__(self, card_number):
        self.card_number = card_number
    
    def pay(self, amount):
        return f"使用信用卡 {self.card_number[-4:]} 支付 ${amount}"

class PayPalPayment(PaymentStrategy):
    """PayPal支付"""
    def __init__(self, email):
        self.email = email
    
    def pay(self, amount):
        return f"使用PayPal账户 {self.email} 支付 ${amount}"

class BankTransferPayment(PaymentStrategy):
    """银行转账支付"""
    def __init__(self, account_number):
        self.account_number = account_number
    
    def pay(self, amount):
        return f"使用银行账户 {self.account_number} 转账 ${amount}"

class PaymentProcessor:
    """支付处理器"""
    def __init__(self):
        self.payment_strategy = None
    
    def set_payment_strategy(self, strategy):
        self.payment_strategy = strategy
    
    def process_payment(self, amount):
        if self.payment_strategy is None:
            raise ValueError("未设置支付策略")
        return self.payment_strategy.pay(amount)

# 使用策略模式
processor = PaymentProcessor()

# 信用卡支付
processor.set_payment_strategy(CreditCardPayment("1234567890123456"))
print(processor.process_payment(100))

# PayPal支付
processor.set_payment_strategy(PayPalPayment("user@example.com"))
print(processor.process_payment(50))

# 银行转账
processor.set_payment_strategy(BankTransferPayment("9876543210"))
print(processor.process_payment(200))

最佳实践

1. 组合优于继承

class Engine:
    """引擎类"""
    def start(self):
        return "引擎启动"
    
    def stop(self):
        return "引擎停止"

class Wheel:
    """轮子类"""
    def __init__(self, position):
        self.position = position
    
    def rotate(self):
        return f"{self.position}轮子转动"

class Car:
    """汽车类 - 使用组合"""
    def __init__(self, engine_type="V6"):
        self.engine = Engine()
        self.wheels = [Wheel(f"前{pos}") for pos in ["左", "右"]] + \
                     [Wheel(f"后{pos}") for pos in ["左", "右"]]
        self.engine_type = engine_type
    
    def start(self):
        return self.engine.start()
    
    def stop(self):
        return self.engine.stop()
    
    def drive(self):
        wheel_actions = [wheel.rotate() for wheel in self.wheels]
        return f"{self.start()}, {', '.join(wheel_actions)}"

# 使用组合
car = Car()
print(car.drive())

2. 接口隔离原则

from abc import ABC, abstractmethod

class Readable(ABC):
    """可读接口"""
    @abstractmethod
    def read(self):
        pass

class Writable(ABC):
    """可写接口"""
    @abstractmethod
    def write(self, data):
        pass

class FileReader(Readable):
    """文件读取器"""
    def __init__(self, filename):
        self.filename = filename
    
    def read(self):
        return f"从 {self.filename} 读取数据"

class FileWriter(Writable):
    """文件写入器"""
    def __init__(self, filename):
        self.filename = filename
    
    def write(self, data):
        return f"向 {self.filename} 写入数据: {data}"

class FileManager(Readable, Writable):
    """文件管理器 - 实现多个接口"""
    def __init__(self, filename):
        self.filename = filename
    
    def read(self):
        return f"从 {self.filename} 读取数据"
    
    def write(self, data):
        return f"向 {self.filename} 写入数据: {data}"

# 使用接口隔离
def process_readable(readable: Readable):
    return readable.read()

def process_writable(writable: Writable, data):
    return writable.write(data)

reader = FileReader("input.txt")
writer = FileWriter("output.txt")
manager = FileManager("data.txt")

print(process_readable(reader))
print(process_writable(writer, "Hello World"))
print(process_readable(manager))
print(process_writable(manager, "Data"))

写在最后

面向对象编程不仅仅是语法特性,更是一种思维方式。它帮助我们:

  1. 抽象现实世界:将复杂的问题分解为对象和关系
  2. 封装复杂性:隐藏实现细节,提供清晰的接口
  3. 实现复用:通过继承和组合重用代码
  4. 提高可维护性:清晰的类层次结构便于理解和修改

Python的面向对象编程体现了"简单而强大"的设计哲学。通过理解类、继承、多态等核心概念,我们能够:

  • 设计更优雅的代码结构
  • 实现更好的代码复用
  • 提高程序的可维护性和扩展性
  • 在面向对象和函数式编程之间找到平衡

记住:面向对象编程不是银弹,但它是一个强大的工具。在合适的场景下使用,能让我们的代码更加清晰和可维护。

相关推荐

Python编程实现求解高次方程_python求次幂
Python编程实现求解高次方程_python求次幂

#头条创作挑战赛#编程求解一元多次方程,一般情况下对于高次方程我们只求出近似解,较少的情况可以得到精确解。这里给出两种经典的方法,一种是牛顿迭代法,它是求解方程根的有效方法,通过若干次迭代(重复执行部分代码,每次使变量的当前值被计算出的新值...

2025-10-23 03:58 itomcoil

python常用得内置函数解析——sorted()函数

接下来我们详细解析Python中非常重要的内置函数sorted()1.函数定义sorted()函数用于对任何可迭代对象进行排序,并返回一个新的排序后的列表。语法:sorted(iterabl...

Python入门学习教程:第 6 章 列表

6.1什么是列表?在Python中,列表(List)是一种用于存储多个元素的有序集合,它是最常用的数据结构之一。列表中的元素可以是不同的数据类型,如整数、字符串、浮点数,甚至可以是另一个列表。列...

Python之函数进阶-函数加强(上)_python怎么用函数

一.递归函数递归是一种编程技术,其中函数调用自身以解决问题。递归函数需要有一个或多个终止条件,以防止无限递归。递归可以用于解决许多问题,例如排序、搜索、解析语法等。递归的优点是代码简洁、易于理解,并...

Python内置函数range_python内置函数int的作用

range类型表示不可变的数字序列,通常用于在for循环中循环指定的次数。range(stop)range(start,stop[,step])range构造器的参数必须为整数(可以是内...

python常用得内置函数解析——abs()函数

大家号这两天主要是几个常用得内置函数详解详细解析一下Python中非常常用的内置函数abs()。1.函数定义abs(x)是Python的一个内置函数,用于返回一个数的绝对值。参数:x...

如何在Python中获取数字的绝对值?

Python有两种获取数字绝对值的方法:内置abs()函数返回绝对值。math.fabs()函数还返回浮点绝对值。abs()函数获取绝对值内置abs()函数返回绝对值,要使用该函数,只需直接调用:a...

贪心算法变种及Python模板_贪心算法几个经典例子python

贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。以下是贪心算法的主要变种、对应的模板和解决的问题特点。1.区间调度问题问题特点需要从一组区间中选择最大数...

Python倒车请注意!负步长range的10个高能用法,让代码效率翻倍

你是否曾遇到过需要倒着处理数据的情况?面对时间序列、日志文件或者矩阵操作,传统的遍历方式往往捉襟见肘。今天我们就来揭秘Python中那个被低估的功能——range的负步长操作,让你的代码优雅反转!一、...

Python中while循环详解_python怎么while循环

Python中的`while`循环是一种基于条件判断的重复执行结构,适用于不确定循环次数但明确终止条件的场景。以下是详细解析:---###一、基本语法```pythonwhile条件表达式:循环体...

简单的python-核心篇-面向对象编程

在Python中,类本身也是对象,这被称为"元类"。这种设计让Python的面向对象编程具有极大的灵活性。classMyClass:"""一个简单的...

简单的python-python3中的不变的元组

golang中没有内置的元组类型,但是多值返回的处理结果模拟了元组的味道。因此,在golang中"元组”只是一个将多个值(可能是同类型的,也可能是不同类型的)绑定在一起的一种便利方法,通常,也...

python中必须掌握的20个核心函数——sorted()函数

sorted()是Python的内置函数,用于对可迭代对象进行排序,返回一个新的排序后的列表,不修改原始对象。一、sorted()的基本用法1.1方法签名sorted(iterable,*,ke...

12 个 Python 高级技巧,让你的代码瞬间清晰、高效

在日常的编程工作中,我们常常追求代码的精简、优雅和高效。你可能已经熟练掌握了列表推导式(listcomprehensions)、f-string和枚举(enumerate)等常用技巧,但有时仍会觉...

Python的10个进阶技巧:写出更快、更省内存、更优雅的代码

在Python的世界里,我们总是在追求效率和可读性的完美平衡。你不需要一个数百行的新框架来让你的代码变得优雅而快速。事实上,真正能带来巨大提升的,往往是那些看似微小、却拥有高杠杆作用的技巧。这些技巧能...