Python入门(10)--面向对象进阶
Python面向对象进阶 🚀
1. 继承与多态 🔄
1.1 继承基础
class Animal:def __init__(self, name, age):self.name = nameself.age = agedef speak(self):passdef describe(self):return f"{self.name} is {self.age} years old"class Dog(Animal):def __init__(self, name, age, breed):super().__init__(name, age) # 调用父类的初始化方法self.breed = breeddef speak(self):return f"{self.name} says Woof!"def describe(self):# 扩展父类的方法return f"{super().describe()} and is a {self.breed}"class Cat(Animal):def __init__(self, name, age, indoor=True):super().__init__(name, age)self.indoor = indoordef speak(self):return f"{self.name} says Meow!"def describe(self):habitat = "indoor" if self.indoor else "outdoor"return f"{super().describe()} and is an {habitat} cat"# 使用示例
dog = Dog("Buddy", 3, "Golden Retriever")
cat = Cat("Whiskers", 2, True)print(dog.describe()) # 输出: Buddy is 3 years old and is a Golden Retriever
print(cat.describe()) # 输出: Whiskers is 2 years old and is an indoor cat
继承的关键概念:
super()
的使用:调用父类方法- 方法重写与扩展
- 构造函数的继承与扩展
- 属性的继承与新增
1.2 多态
让我们通过一个更实际的例子来展示多态的威力:
class Document:def __init__(self, content):self.content = contentdef format(self):passclass PlainText(Document):def format(self):return self.contentclass HTMLDocument(Document):def format(self):return f"<html><body>{self.content}</body></html>"class MarkdownDocument(Document):def format(self):return f"# {self.content}"def process_documents(documents):"""多态函数 - 统一处理不同类型的文档"""for doc in documents:print(f"处理 {doc.__class__.__name__}:")print(doc.format())print("---")# 实际应用
documents = [PlainText("Hello World"),HTMLDocument("Welcome"),MarkdownDocument("Title")
]process_documents(documents)
1.3 多重继承
让我们通过一个更实用的场景来展示多重继承:
class Persistable:"""提供持久化功能的混入类"""def save(self, filename):with open(filename, 'w') as f:f.write(str(self.__dict__))def load(self, filename):with open(filename, 'r') as f:data = eval(f.read())self.__dict__.update(data)class Loggable:"""提供日志功能的混入类"""def log(self, message):print(f"[{self.__class__.__name__}] {message}")class Configuration(Persistable, Loggable):"""应用配置类"""def __init__(self, host="localhost", port=8000):self.host = hostself.port = portdef update_config(self, **kwargs):self.log("Updating configuration...")self.__dict__.update(kwargs)self.log("Configuration updated")# 使用示例
config = Configuration()
config.update_config(host="127.0.0.1", port=5000)
config.save("config.txt") # 保存配置
config.load("config.txt") # 加载配置
2. 封装与访问控制 🔒
让我们通过一个更完整的例子来展示Python的封装机制:
class Employee:def __init__(self, name, salary):self._name = name # 受保护的属性self.__salary = salary # 私有属性self.__bonus = 0 # 私有属性@propertydef name(self):"""只读属性"""return self._name@propertydef total_salary(self):"""计算总薪资(基本工资 + 奖金)"""return self.__salary + self.__bonus@propertydef bonus(self):"""奖金查询"""return self.__bonus@bonus.setterdef bonus(self, value):"""设置奖金,带验证"""if not isinstance(value, (int, float)):raise TypeError("奖金必须是数字")if value < 0:raise ValueError("奖金不能为负数")self.__bonus = valuedef _calculate_tax(self):"""受保护的方法 - 计算税收"""return self.total_salary * 0.2def get_salary_info(self):"""公开方法 - 获取薪资信息"""return {'name': self._name,'total_salary': self.total_salary,'tax': self._calculate_tax(),'net_salary': self.total_salary - self._calculate_tax()}# 使用示例
emp = Employee("John Doe", 5000)# 属性访问
print(emp.name) # 使用@property
emp.bonus = 1000 # 使用@bonus.setter
print(emp.total_salary) # 使用@property计算总薪资# 获取完整信息
salary_info = emp.get_salary_info()
for key, value in salary_info.items():print(f"{key}: {value}")# 以下操作会引发错误
# emp.name = "Jane" # AttributeError: 不能修改只读属性
# emp.__salary = 6000 # AttributeError: 私有属性不能直接访问
# emp.bonus = -100 # ValueError: 奖金不能为负数
补充说明:
- 使用
@property
创建只读属性 - 使用
@property
和@x.setter
创建可读写属性 - 使用单下划线表示受保护成员
- 使用双下划线表示私有成员
- 通过公开方法提供对私有数据的安全访问
3. 类方法与静态方法 🛠️
3.1 类方法(@classmethod)
让我们通过一个更实用的工厂模式示例来展示类方法的应用:
from datetime import datetime, dateclass Order:"""订单类"""order_count = 0 # 类变量,用于追踪订单数量def __init__(self, customer_id: str, items: list, order_date: date):Order.order_count += 1self.order_id = f"ORD{Order.order_count:04d}"self.customer_id = customer_idself.items = itemsself.order_date = order_dateself.status = "pending"@classmethoddef create_from_dict(cls, order_data: dict):"""从字典创建订单对象"""try:customer_id = order_data['customer_id']items = order_data['items']# 解析日期字符串date_str = order_data.get('date', datetime.now().strftime('%Y-%m-%d'))order_date = datetime.strptime(date_str, '%Y-%m-%d').date()return cls(customer_id, items, order_date)except KeyError as e:raise ValueError(f"缺少必要的订单信息: {e}")@classmethoddef create_rush_order(cls, customer_id: str, items: list):"""创建加急订单"""order = cls(customer_id, items, date.today())order.status = "rush"return order@classmethoddef get_order_count(cls) -> int:"""获取订单总数"""return cls.order_countdef __str__(self):return f"Order {self.order_id}: {len(self.items)} items for {self.customer_id}"# 使用示例
# 1. 常规创建
order1 = Order("CUST001", ["item1", "item2"], date.today())# 2. 从字典创建
order_data = {"customer_id": "CUST002","items": ["item3", "item4"],"date": "2024-03-15"
}
order2 = Order.create_from_dict(order_data)# 3. 创建加急订单
rush_order = Order.create_rush_order("CUST003", ["urgent_item"])print(f"Total orders: {Order.get_order_count()}") # 输出订单总数
3.2 静态方法(@staticmethod)
通过一个更复杂的示例来展示静态方法的实际应用:
class DataValidator:"""数据验证工具类"""@staticmethoddef validate_email(email: str) -> bool:"""验证邮箱格式"""import repattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'return bool(re.match(pattern, email))@staticmethoddef validate_phone(phone: str) -> bool:"""验证电话号码格式"""import re# 支持多种格式:+86-123-4567-8901, 12345678901, 123-4567-8901patterns = [r'^\+\d{1,3}-\d{3}-\d{4}-\d{4}$',r'^\d{11}$',r'^\d{3}-\d{4}-\d{4}$']return any(bool(re.match(pattern, phone)) for pattern in patterns)@staticmethoddef validate_date(date_str: str) -> bool:"""验证日期格式和有效性"""try:datetime.strptime(date_str, '%Y-%m-%d')return Trueexcept ValueError:return False@staticmethoddef sanitize_string(text: str) -> str:"""清理并验证字符串"""# 移除首尾空白,替换多个空格为单个空格text = ' '.join(text.split())# 移除特殊字符text = ''.join(char for char in text if char.isprintable())return textclass UserProfile:"""用户档案类 - 展示数据验证的应用"""def __init__(self, email: str, phone: str, birth_date: str):if not DataValidator.validate_email(email):raise ValueError("无效的邮箱地址")if not DataValidator.validate_phone(phone):raise ValueError("无效的电话号码")if not DataValidator.validate_date(birth_date):raise ValueError("无效的出生日期")self.email = emailself.phone = phoneself.birth_date = birth_date# 使用示例
try:# 创建用户档案user = UserProfile(email="john.doe@example.com",phone="123-4567-8901",birth_date="1990-01-01")print("用户档案创建成功")# 验证和清理数据text = " Hello World! \n\t@#$% "cleaned = DataValidator.sanitize_string(text)print(f"清理后的文本: '{cleaned}'")except ValueError as e:print(f"错误: {e}")
4. 抽象类与接口 🎯
让我们通过一个文件处理系统的例子来展示抽象类和接口的实际应用:
from abc import ABC, abstractmethod
from typing import Any, List, Dict
import json
import csv
import xml.etree.ElementTree as ETclass DataProcessor(ABC):"""数据处理器抽象基类"""@abstractmethoddef read(self, source: str) -> Any:"""读取数据"""pass@abstractmethoddef write(self, data: Any, destination: str) -> bool:"""写入数据"""pass@abstractmethoddef validate(self, data: Any) -> bool:"""验证数据"""pass@property@abstractmethoddef supported_extensions(self) -> List[str]:"""支持的文件扩展名"""passclass JSONProcessor(DataProcessor):"""JSON数据处理器"""@propertydef supported_extensions(self) -> List[str]:return ['.json']def validate(self, data: Any) -> bool:if not isinstance(data, (dict, list)):return Falsetry:json.dumps(data) # 测试是否可序列化return Trueexcept (TypeError, ValueError):return Falsedef read(self, source: str) -> Any:try:with open(source, 'r', encoding='utf-8') as f:return json.load(f)except json.JSONDecodeError as e:raise ValueError(f"JSON解析错误: {e}")def write(self, data: Any, destination: str) -> bool:if not self.validate(data):raise ValueError("无效的JSON数据")try:with open(destination, 'w', encoding='utf-8') as f:json.dump(data, f, indent=2, ensure_ascii=False)return Trueexcept Exception as e:print(f"写入错误: {e}")return Falseclass CSVProcessor(DataProcessor):"""CSV数据处理器"""@propertydef supported_extensions(self) -> List[str]:return ['.csv']def validate(self, data: Any) -> bool:return isinstance(data, list) and all(isinstance(row, dict) for row in data)def read(self, source: str) -> List[Dict]:try:with open(source, 'r', encoding='utf-8') as f:return list(csv.DictReader(f))except Exception as e:raise ValueError(f"CSV读取错误: {e}")def write(self, data: List[Dict], destination: str) -> bool:if not self.validate(data):raise ValueError("无效的CSV数据格式")try:with open(destination, 'w', newline='', encoding='utf-8') as f:if not data:return Truewriter = csv.DictWriter(f, fieldnames=data[0].keys())writer.writeheader()writer.writerows(data)return Trueexcept Exception as e:print(f"写入错误: {e}")return Falseclass DataProcessorFactory:"""数据处理器工厂"""_processors: Dict[str, DataProcessor] = {'.json': JSONProcessor(),'.csv': CSVProcessor()}@classmethoddef get_processor(cls, file_path: str) -> DataProcessor:"""根据文件扩展名获取相应的处理器"""import osext = os.path.splitext(file_path)[1].lower()processor = cls._processors.get(ext)if not processor:raise ValueError(f"不支持的文件类型: {ext}")return processor# 使用示例
def convert_file(source: str, destination: str):"""文件转换功能"""try:# 获取源文件和目标文件的处理器source_processor = DataProcessorFactory.get_processor(source)dest_processor = DataProcessorFactory.get_processor(destination)# 读取源文件data = source_processor.read(source)# 写入目标文件if dest_processor.write(data, destination):print(f"文件转换成功: {source} -> {destination}")else:print("文件转换失败")except Exception as e:print(f"转换错误: {e}")# 测试文件转换
if __name__ == "__main__":# JSON到CSV的转换convert_file("data.json", "output.csv")# CSV到JSON的转换convert_file("data.csv", "output.json")
5. 实战案例:图形计算器 📐
让我们创建一个图形计算器,它能够处理不同类型的图形,计算它们的面积和周长:
from abc import ABC, abstractmethod
from typing import List
import mathclass Shape(ABC):"""抽象基类:形状"""@abstractmethoddef area(self) -> float:"""计算面积"""pass@abstractmethoddef perimeter(self) -> float:"""计算周长"""pass@abstractmethoddef description(self) -> str:"""返回形状描述"""passclass Rectangle(Shape):"""矩形类"""def __init__(self, width: float, height: float):if width <= 0 or height <= 0:raise ValueError("矩形的宽和高必须为正数")self._width = widthself._height = heightdef area(self) -> float:return self._width * self._heightdef perimeter(self) -> float:return 2 * (self._width + self._height)def description(self) -> str:return f"矩形(宽={self._width}, 高={self._height})"class Circle(Shape):"""圆形类"""def __init__(self, radius: float):if radius <= 0:raise ValueError("圆的半径必须为正数")self._radius = radiusdef area(self) -> float:return math.pi * self._radius ** 2def perimeter(self) -> float:return 2 * math.pi * self._radiusdef description(self) -> str:return f"圆形(半径={self._radius})"class Triangle(Shape):"""三角形类"""def __init__(self, a: float, b: float, c: float):if not self._is_valid_triangle(a, b, c):raise ValueError("无效的三角形边长")self._sides = (a, b, c)@staticmethoddef _is_valid_triangle(a: float, b: float, c: float) -> bool:"""检查三条边是否能构成三角形"""return (a > 0 and b > 0 and c > 0 anda + b > c and b + c > a and a + c > b)def area(self) -> float:"""使用海伦公式计算面积"""a, b, c = self._sidess = (a + b + c) / 2 # 半周长return math.sqrt(s * (s - a) * (s - b) * (s - c))def perimeter(self) -> float:return sum(self._sides)def description(self) -> str:return f"三角形(边长={', '.join(map(str, self._sides))})"class GeometryCalculator:"""几何计算器类"""def __init__(self):self._shapes: List[Shape] = []def add_shape(self, shape: Shape):"""添加形状"""self._shapes.append(shape)print(f"已添加: {shape.description()}")def calculate_total_area(self) -> float:"""计算所有形状的总面积"""return sum(shape.area() for shape in self._shapes)def calculate_total_perimeter(self) -> float:"""计算所有形状的总周长"""return sum(shape.perimeter() for shape in self._shapes)def show_all_shapes(self):"""显示所有形状的信息"""print("\n形状列表:")for i, shape in enumerate(self._shapes, 1):print(f"{i}. {shape.description()}")print(f" 面积: {shape.area():.2f}")print(f" 周长: {shape.perimeter():.2f}")def main():# 创建计算器实例calculator = GeometryCalculator()# 添加一些形状try:calculator.add_shape(Rectangle(5, 3))calculator.add_shape(Circle(4))calculator.add_shape(Triangle(3, 4, 5))# 显示所有形状信息calculator.show_all_shapes()# 显示总计print(f"\n总面积: {calculator.calculate_total_area():.2f}")print(f"总周长: {calculator.calculate_total_perimeter():.2f}")except ValueError as e:print(f"错误: {e}")if __name__ == "__main__":main()
实战案例特点:
- 抽象基类:使用
Shape
作为抽象基类,定义了必须实现的方法 - 继承与多态:各种具体图形类继承自
Shape
类 - 封装:使用私有属性保护数据
- 类型提示:使用
typing
模块增加代码可读性 - 错误处理:包含适当的验证和异常处理
- 静态方法:用于辅助功能(如三角形的有效性检查)
扩展建议:
- 添加更多图形类型(如多边形、椭圆等)
- 实现图形的缩放和旋转
- 添加图形的绘制功能
- 实现文件保存和加载功能
- 添加图形组合功能
- 实现简单的GUI界面
- 添加单位转换功能
这个实战案例展示了面向对象编程的进阶概念,包括继承、多态、封装和抽象类的实际应用。它提供了一个可扩展的框架,可以根据需要添加更多功能。
如果你觉得这篇文章有帮助,欢迎点赞转发,也期待在评论区看到你的想法和建议!👇
咱们下一期见!
相关文章:
Python入门(10)--面向对象进阶
Python面向对象进阶 🚀 1. 继承与多态 🔄 1.1 继承基础 class Animal:def __init__(self, name, age):self.name nameself.age agedef speak(self):passdef describe(self):return f"{self.name} is {self.age} years old"class Dog(Anim…...
Makefile 之 自动化变量
作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。 "$" 表示目标的集合,就像一个数组,"$"依次取出目标,并执于命令。 "$<"和"$&qu…...

鸿蒙开发:ForEach中为什么键值生成函数很重要
前言 在列表组件使用的时候,如List、Grid、WaterFlow等,循环渲染时都会使用到ForEach或者LazyForEach,当然了,也有单独使用的场景,如下,一个很简单的列表组件使用,这种使用方式,在官…...

沃丰科技智能外呼机器人:超越人工,重塑外呼体验
随着科技的不断发展,人工智能已经逐渐渗透到各行各业,其中智能外呼机器人的出现,更是给企业带来了全新的客户体验。与传统的人工外呼相比,智能外呼机器人具有更高的效率、更低的成本以及更好的用户体验等优势。 优势一࿱…...
百度飞浆:paddle 线性回归模型
学习引用 参考视频: https://www.bilibili.com/video/BV1oRtkeVEVx?spm_id_from333.788.player.switch&vd_sourcec7739de98d044e74cdc74d6e772bed5f&p2 这段代码使用PaddlePaddle深度学习框架来实现一个简单的线性回归模型,旨在从给定的出租车…...

【JavaSE】【网络编程】UDP数据报套接字编程
目录 一、网络编程简介二、Socket套接字三、TCP/UDP简介3.1 有连接 vs 无连接3.2 可靠传输 vs 不可靠传输3.3 面向字节流 vs 面向数据报3.4 双向工 vs 单行工 四、UDP数据报套接字编程4.1 API介绍4.1.1 DatagramSocket类4.1.1.1 构造方法4.1.1.2 主要方法 4.1.2 DatagramPocket…...

45.坑王驾到第九期:Mac安装typescript后tsc命令无效的问题
点赞收藏加关注,你也能主打别墅! 一、问题描述 Mac上终端运行如下命令: sudo npm install typescript -g //全局安装ts提示成功安装后,我测试tsc -v这个命令时出现如下错误: 也就是说找不到 tsc 命令。 二、解决方…...

20241120-Milvus向量数据库快速体验
目录 20241120-Milvus向量数据库快速体验Milvus 向量数据库pymilvus内嵌向量数据库模式设置向量数据库创建 Collections准备数据用向量表示文本插入数据 语义搜索向量搜索带元数据过滤的向量搜索查询通过主键搜索 删除实体加载现有数据删除 Collections了解更多 个人主页: 【⭐…...

【Golang】——Gin 框架中间件详解:从基础到实战
中间件是 Web 应用开发中常见的功能模块,Gin 框架支持自定义和使用内置的中间件,让你在请求到达路由处理函数前进行一系列预处理操作。这篇博客将涵盖中间件的概念、内置中间件的用法、如何编写自定义中间件,以及在实际应用中的一些最佳实践。…...

量子计算来袭:如何保护未来的数字世界
目录 前言 一、量子计算安全的学习方向 1. 量子物理学基础 2. 量子计算原理与技术 3. 传统网络安全知识 4. 量子密码学 5. 量子计算安全政策与法规 二、量子计算的漏洞风险 1. 加密算法被破解风险 2. 区块链安全风险 3. 量子密钥分发风险 4. 量子计算系统自身风险 …...

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源
VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源 由于需要在 Linux 环境下进行一些测试工作,于是决定使用 VMware 虚拟化软件来安装 Ubuntu 24.04 .1操作系统。考虑到测试过程中需要访问 Github ,要使用Docker拉去镜像等外部网络资源,因此产…...

光伏电站仿真系统的作用
光伏仿真系统有多方面的重要作用,不仅对前期的项目设计评估还是后期的运维效验都有非常重要的作用。 1、优化系统设计 通过输入不同的光伏组件参数、布局方案以及气象条件等,模拟各种设计场景下光伏电站的性能表现。例如,可以比较不同类型光…...
Golang文件操作
写文件 &emsp; os模块可以创建文件,使用fmt可以写入文件。如以下例子: package mainimport ("fmt""os" )func main() {// 学习 golang的文件操作file, err : os.Create("test.txt")if err ! nil {fmt.P…...

爬虫开发工具与环境搭建——使用Postman和浏览器开发者工具
第三节:使用Postman和浏览器开发者工具 在网络爬虫开发过程中,我们经常需要对HTTP请求进行测试、分析和调试。Postman和浏览器开发者工具(特别是Network面板和Console面板)是两种最常用的工具,能够帮助开发者有效地捕…...

React(二)
文章目录 项目地址七、数据流7.1 子组件传递数据给父组件7.1.1 方式一:給父设置回调函数,传递给子7.1.2 方式二:直接将父的setState传递给子7.2 给props传递jsx7.2.1 方式一:直接传递组件给子类7.2.2 方式二:传递函数给子组件7.3 props类型验证7.4 props的多层传递7.5 cla…...
同步原语(Synchronization Primitives)
同步原语(Synchronization Primitives)是用于控制并发编程中多个线程或进程之间的访问顺序,确保共享资源的安全访问的一组机制或工具。它们解决了竞争条件(Race Condition)、死锁(Deadlock)等并…...
SpringBoot服务多环境配置
一个项目的的环境一般有三个:开发(dev)、测试(test)、生产(proc),一般对应三套环境,三套配置文件。 像下面这样直接写两个配置文件是不行的。 application.ymlserver:port: 8080application-dev.ymlspring:datasource:driver-class-name: co…...

STM32单片机CAN总线汽车线路通断检测-分享
目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着汽车电子技术的不断发展,车辆通信接口在汽车电子控…...

【环境搭建】使用IDEA远程调试Docker中的Java Web
有时候要对Docker的Java Web远程调试其功能,于是就需要使用IDEA的远程调试功能,记录一下简单配置方法。 以Kylin4.0.0为例,首先拉取镜像并启动容器: $ docker pull apachekylin/apache-kylin-standalone:4.0.0$ docker run -d \-…...

贴代码框架PasteForm特性介绍之select,selects,lselect和reload
简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...

Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...