简单的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"))
写在最后
面向对象编程不仅仅是语法特性,更是一种思维方式。它帮助我们:
- 抽象现实世界:将复杂的问题分解为对象和关系
- 封装复杂性:隐藏实现细节,提供清晰的接口
- 实现复用:通过继承和组合重用代码
- 提高可维护性:清晰的类层次结构便于理解和修改
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的世界里,我们总是在追求效率和可读性的完美平衡。你不需要一个数百行的新框架来让你的代码变得优雅而快速。事实上,真正能带来巨大提升的,往往是那些看似微小、却拥有高杠杆作用的技巧。这些技巧能...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)