Python OOP核心技巧:如何正确选择实例方法、类方法和静态方法

Python方法类型全解析:实例方法、类方法与静态方法的使用场景

    • 一、三种方法的基本区别
    • 二、访问能力对比表
    • 三、何时使用实例方法
      • 使用实例方法的核心场景:
      • 具体应用场景:
        • 1. 操作实例属性
        • 2. 对象间交互
        • 3. 实现特定实例的行为
    • 四、何时使用类方法
      • 使用类方法的核心场景:
      • 具体应用场景:
        • 1. 替代构造函数(工厂方法)
        • 2. 操作类变量(计数器、配置等)
        • 3. 创建与多个实例共享的功能
        • 4. 子类多态性
    • 五、何时使用静态方法
      • 使用静态方法的核心场景:
      • 具体应用场景:
        • 1. 辅助验证和检查
        • 2. 格式化和转换功能
        • 3. 工具函数
        • 4. 与系统或框架交互的辅助函数
    • 六、方法类型选择决策流程
    • 七、混合使用的实际案例
    • 八、总结
      • 使用实例方法的情况:
      • 使用类方法的情况:
      • 使用静态方法的情况:

一、三种方法的基本区别

首先,让我们通过一个简单示例明确三种方法的基本语法和区别:

class Example:count = 0  # 类变量:所有实例共享的计数器def __init__(self, name):self.name = name  # 实例变量:每个对象特有的名称属性Example.count += 1  # 每创建一个实例,计数器加1# 实例方法:第一个参数是self,代表实例本身def instance_method(self):"""实例方法:可访问实例属性和类属性"""print(f"这是实例方法,能访问:self.name={self.name}, self.__class__.count={self.__class__.count}")return "实例方法返回"# 类方法:第一个参数是cls,使用@classmethod装饰器@classmethoddef class_method(cls):"""类方法:接收类作为第一个参数,可直接访问类属性"""print(f"这是类方法,能访问:cls.count={cls.count}")return "类方法返回"# 静态方法:没有特殊的第一个参数,使用@staticmethod装饰器@staticmethoddef static_method():"""静态方法:不接收特殊的第一个参数,无法直接访问类或实例属性"""print("这是静态方法,不能直接访问类或实例的属性")return "静态方法返回"

二、访问能力对比表

方法类型装饰器第一个参数能否访问实例变量能否访问类变量能否在不创建实例的情况下调用
实例方法self✓(通过self.class
类方法@classmethodcls
静态方法@staticmethod

三、何时使用实例方法

使用实例方法的核心场景:

  1. 需要访问或修改实例状态
  2. 表示对象特有的行为
  3. 实现对象之间的交互

具体应用场景:

1. 操作实例属性
class BankAccount:def __init__(self, account_number, balance=0):self.account_number = account_number  # 账号:每个账户唯一的标识符self.balance = balance  # 余额:账户中的资金数量self.transactions = []  # 交易记录:存储所有交易历史# 实例方法:操作特定账户的余额def deposit(self, amount):"""存款方法:增加账户余额并记录交易"""if amount <= 0:raise ValueError("存款金额必须为正数")self.balance += amountself.transactions.append(f"存款: +{amount}")return self.balancedef withdraw(self, amount):"""取款方法:减少账户余额并记录交易"""if amount <= 0:raise ValueError("取款金额必须为正数")if amount > self.balance:raise ValueError("余额不足")self.balance -= amountself.transactions.append(f"取款: -{amount}")return self.balancedef get_statement(self):"""获取账单方法:生成账户状态报告"""statement = f"账号: {self.account_number}\n"statement += f"当前余额: {self.balance}\n"statement += "交易记录:\n"for transaction in self.transactions:statement += f"- {transaction}\n"return statement
2. 对象间交互
class Person:def __init__(self, name, age):self.name = name  # 姓名:人物的名称标识self.age = age  # 年龄:人物的年龄self.friends = []  # 朋友列表:存储该人物的所有朋友对象# 实例方法:处理对象间关系def add_friend(self, friend):"""添加朋友方法:建立双向的朋友关系"""if friend not in self.friends:self.friends.append(friend)# 建立双向关系:如果对方尚未将自己添加为朋友,则添加friend.add_friend(self) if friend != self else Nonedef introduce(self):"""自我介绍方法:生成包含朋友信息的介绍语"""if not self.friends:return f"我是{self.name}{self.age}岁,我还没有朋友。"friends_names = [friend.name for friend in self.friends]return f"我是{self.name}{self.age}岁,我的朋友有:{', '.join(friends_names)}"# 使用示例
alice = Person("Alice", 25)
bob = Person("Bob", 27)
alice.add_friend(bob)print(alice.introduce())  # 输出: 我是Alice,25岁,我的朋友有:Bob
print(bob.introduce())    # 输出: 我是Bob,27岁,我的朋友有:Alice
3. 实现特定实例的行为
class Shape:def __init__(self, color):self.color = color  # 颜色:形状的颜色属性# 实例方法:每个形状计算面积的方式不同def area(self):"""面积计算方法:由子类实现具体计算方式"""raise NotImplementedError("子类必须实现这个方法")def describe(self):"""描述方法:提供形状的基本描述"""return f"这是一个{self.color}的形状"class Circle(Shape):def __init__(self, color, radius):super().__init__(color)self.radius = radius  # 半径:圆的特有属性def area(self):"""圆面积计算方法:实现具体的面积计算逻辑"""import mathreturn math.pi * self.radius ** 2def describe(self):"""圆描述方法:重写父类方法,提供圆特有的描述"""return f"这是一个{self.color}的圆,半径为{self.radius}"class Rectangle(Shape):def __init__(self, color, width, height):super().__init__(color)self.width = width  # 宽度:矩形的宽度属性self.height = height  # 高度:矩形的高度属性def area(self):"""矩形面积计算方法:实现具体的面积计算逻辑"""return self.width * self.heightdef describe(self):"""矩形描述方法:重写父类方法,提供矩形特有的描述"""return f"这是一个{self.color}的矩形,宽{self.width},高{self.height}"

四、何时使用类方法

使用类方法的核心场景:

  1. 替代构造函数(工厂方法)
  2. 操作类变量
  3. 创建与类本身相关,而非具体实例的方法
  4. 定义子类可重写但仍需访问类属性的方法

具体应用场景:

1. 替代构造函数(工厂方法)
class Person:def __init__(self, first_name, last_name, age):self.first_name = first_name  # 名:人的名字self.last_name = last_name  # 姓:人的姓氏self.age = age  # 年龄:人的年龄@classmethoddef from_full_name(cls, full_name, age):"""从全名创建Person实例的工厂方法"""# 处理中文名字情况:李四 → 李(姓)、四(名)if " " in full_name:first_name, last_name = full_name.split(" ", 1)else:# 假设中文名字第一个字是姓,其余是名first_name = full_name[0]  # 姓last_name = full_name[1:]  # 名return cls(first_name, last_name, age)@classmethoddef from_birth_year(cls, first_name, last_name, birth_year):"""从出生年份创建Person实例的工厂方法"""import datetimecurrent_year = datetime.datetime.now().yearage = current_year - birth_yearreturn cls(first_name, last_name, age)def __str__(self):"""字符串表示方法:提供对象的可读性表示"""return f"{self.first_name} {self.last_name}, {self.age}岁"# 使用默认构造函数
p1 = Person("张", "三", 25)
print(p1)  # 输出: 张 三, 25岁# 使用替代构造函数
p2 = Person.from_full_name("李四", 30)
print(p2)  # 输出: 李 四, 30岁p3 = Person.from_birth_year("王", "五", 1990)
print(p3)  # 输出: 王 五, 34岁(2024年)
2. 操作类变量(计数器、配置等)
class Database:connections = 0  # 类变量:跟踪当前连接数max_connections = 5  # 类变量:最大允许连接数connection_pool = []  # 类变量:存储所有活跃连接的列表def __init__(self, name):"""初始化数据库连接"""if Database.connections >= Database.max_connections:raise RuntimeError("达到最大连接数限制")self.name = name  # 数据库名称:连接的标识符Database.connections += 1  # 增加连接计数Database.connection_pool.append(self)  # 添加到连接池print(f"创建到数据库{name}的连接,当前连接数: {Database.connections}")def __del__(self):"""析构方法:清理连接资源"""Database.connections -= 1  # 减少连接计数if self in Database.connection_pool:Database.connection_pool.remove(self)  # 从连接池移除print(f"关闭到数据库{self.name}的连接,当前连接数: {Database.connections}")@classmethoddef get_connection_count(cls):"""获取当前连接数的类方法"""return cls.connections@classmethoddef set_max_connections(cls, max_conn):"""设置最大连接数的类方法"""if max_conn <= 0:raise ValueError("最大连接数必须为正数")cls.max_connections = max_connprint(f"最大连接数已设置为: {cls.max_connections}")@classmethoddef get_connection_pool_info(cls):"""获取连接池信息的类方法"""return {"total": cls.connections,  # 当前连接总数"max": cls.max_connections,  # 最大允许连接数"available": cls.max_connections - cls.connections,  # 可用连接数"databases": [conn.name for conn in cls.connection_pool]  # 已连接的数据库列表}
3. 创建与多个实例共享的功能
class FileHandler:supported_formats = ['txt', 'csv', 'json']  # 类变量:支持的文件格式列表default_encoding = 'utf-8'  # 类变量:默认文件编码def __init__(self, filename):self.filename = filename  # 文件名:处理的文件路径self.content = None  # 内容:存储文件读取的内容def read(self):"""读取文件方法:从文件中读取内容"""with open(self.filename, 'r', encoding=self.default_encoding) as f:self.content = f.read()return self.content@classmethoddef get_supported_formats(cls):"""获取支持的文件格式:返回所有支持的格式列表"""return cls.supported_formats@classmethoddef add_supported_format(cls, format_name):"""添加支持的文件格式:扩展可处理的文件类型"""if format_name not in cls.supported_formats:cls.supported_formats.append(format_name)print(f"已添加对{format_name}格式的支持")@classmethoddef is_supported(cls, filename):"""检查文件格式支持:判断文件是否为支持的格式"""ext = filename.split('.')[-1].lower() if '.' in filename else ''return ext in cls.supported_formats@classmethoddef set_default_encoding(cls, encoding):"""设置默认编码:修改所有实例使用的默认编码"""cls.default_encoding = encodingprint(f"默认编码已设置为: {encoding}")
4. 子类多态性
class Animal:species_count = {}  # 类变量:存储各物种数量的字典def __init__(self, name):self.name = name  # 名称:动物的名字# 更新该物种的数量统计cls = self.__class__cls.register_animal()@classmethoddef register_animal(cls):"""注册一个新动物实例:增加该物种的计数"""cls_name = cls.__name__  # 获取具体子类的名称Animal.species_count[cls_name] = Animal.species_count.get(cls_name, 0) + 1@classmethoddef get_species_count(cls):"""获取特定物种的数量:返回当前类的实例计数"""return Animal.species_count.get(cls.__name__, 0)@classmethoddef get_all_species_stats(cls):"""获取所有物种统计:返回所有物种的数量信息"""return Animal.species_countclass Dog(Animal):"""狗类:Animal的子类"""passclass Cat(Animal):"""猫类:Animal的子类"""pass# 创建动物实例
d1 = Dog("旺财")
d2 = Dog("小黑")
c1 = Cat("咪咪")# 获取物种统计
print(f"狗的数量: {Dog.get_species_count()}")  # 输出: 狗的数量: 2
print(f"猫的数量: {Cat.get_species_count()}")  # 输出: 猫的数量: 1
print(f"所有物种统计: {Animal.get_all_species_stats()}")  # 输出: 所有物种统计: {'Dog': 2, 'Cat': 1}

五、何时使用静态方法

使用静态方法的核心场景:

  1. 与类相关但不需要访问类状态的辅助功能
  2. 不依赖于类或实例状态的纯功能
  3. 在类命名空间中组织相关功能
  4. 工具函数,但与类主题相关

具体应用场景:

1. 辅助验证和检查
class User:def __init__(self, username, email, password):# 先验证输入if not User.is_valid_username(username):raise ValueError("无效的用户名")if not User.is_valid_email(email):raise ValueError("无效的邮箱")if not User.is_strong_password(password):raise ValueError("密码强度不足")self.username = username  # 用户名:用户的登录标识self.email = email  # 邮箱:用户的电子邮件地址self._password = User.hash_password(password)  # 密码:经过哈希处理的密码存储@staticmethoddef is_valid_username(username):"""检查用户名是否有效:验证用户名格式"""import repattern = r'^[a-zA-Z0-9_]{3,20}$'  # 用户名规则:字母数字下划线,3-20个字符return bool(re.match(pattern, username))@staticmethoddef is_valid_email(email):"""检查邮箱是否有效:验证邮箱格式"""import repattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'  # 标准邮箱格式return bool(re.match(pattern, email))@staticmethoddef is_strong_password(password):"""检查密码是否足够强:验证密码复杂度"""if len(password) < 8:  # 检查长度return Falsehas_upper = any(c.isupper() for c in password)  # 检查是否包含大写字母has_lower = any(c.islower() for c in password)  # 检查是否包含小写字母has_digit = any(c.isdigit() for c in password)  # 检查是否包含数字return has_upper and has_lower and has_digit  # 返回密码强度检查结果@staticmethoddef hash_password(password):"""密码哈希处理:提供密码的安全存储方式"""import hashlibreturn hashlib.sha256(password.encode()).hexdigest()  # 使用SHA-256进行哈希def check_password(self, password):"""检查密码是否匹配:验证用户密码"""hashed = User.hash_password(password)  # 对输入密码进行哈希return hashed == self._password  # 比较哈希值
2. 格式化和转换功能
class DataProcessor:def __init__(self, data):self.data = data  # 数据:要处理的原始数据def process(self):"""处理数据方法:对实例数据进行处理"""# 处理数据...processed_data = self.datareturn processed_data@staticmethoddef csv_to_list(csv_string):"""CSV转列表:将CSV字符串解析为二维列表"""lines = csv_string.strip().split('\n')  # 按行分割return [line.split(',') for line in lines]  # 每行按逗号分割@staticmethoddef list_to_csv(data_list):"""列表转CSV:将二维列表转换为CSV字符串"""return '\n'.join(','.join(map(str, row)) for row in data_list)  # 合并行和列@staticmethoddef json_to_dict(json_string):"""JSON转字典:解析JSON字符串为Python字典"""import jsonreturn json.loads(json_string)  # 使用json模块解析@staticmethoddef dict_to_json(data_dict):"""字典转JSON:将Python字典序列化为JSON字符串"""import jsonreturn json.dumps(data_dict, indent=2)  # 使用json模块序列化,添加缩进@staticmethoddef format_timestamp(timestamp):"""格式化时间戳:将时间戳转换为可读日期时间"""import datetimedt = datetime.datetime.fromtimestamp(timestamp)  # 转换为datetime对象return dt.strftime("%Y-%m-%d %H:%M:%S")  # 格式化输出
3. 工具函数
class MathUtils:@staticmethoddef is_prime(n):"""判断质数:检查一个数是否为质数"""if n <= 1:  # 1和负数不是质数return Falseif n <= 3:  # 2和3是质数return Trueif n % 2 == 0 or n % 3 == 0:  # 排除能被2或3整除的数return Falsei = 5while i * i <= n:  # 只需检查到平方根if n % i == 0 or n % (i + 2) == 0:return Falsei += 6  # 优化:只检查6k±1的数return True@staticmethoddef gcd(a, b):"""最大公约数:计算两个数的最大公因数"""while b:  # 使用欧几里得算法a, b = b, a % breturn a@staticmethoddef lcm(a, b):"""最小公倍数:计算两个数的最小公倍数"""return a * b // MathUtils.gcd(a, b)  # 使用公式:a*b/gcd(a,b)@staticmethoddef factorial(n):"""阶乘函数:计算n的阶乘"""if n < 0:  # 验证输入raise ValueError("阶乘不能用于负数")result = 1for i in range(2, n + 1):  # 遍历计算result *= ireturn result@staticmethoddef fibonacci(n):"""斐波那契数列:生成第n个斐波那契数"""if n <= 0:  # 边界条件处理return 0if n == 1:return 1a, b = 0, 1  # 初始化前两个数for _ in range(2, n + 1):  # 迭代计算a, b = b, a + b  # 更新值return b  # 返回结果
4. 与系统或框架交互的辅助函数
class FileSystem:@staticmethoddef ensure_directory_exists(directory_path):"""确保目录存在:如不存在则创建目录"""import osif not os.path.exists(directory_path):  # 检查目录是否存在os.makedirs(directory_path)  # 创建目录及其父目录return True  # 表示创建了新目录return False  # 表示目录已存在@staticmethoddef is_file_empty(file_path):"""检查文件是否为空:通过文件大小判断"""import osreturn os.path.getsize(file_path) == 0  # 文件大小为0则为空@staticmethoddef get_file_extension(file_path):"""获取文件扩展名:提取文件后缀"""import osreturn os.path.splitext(file_path)[1]  # 分割文件名和扩展名@staticmethoddef get_files_by_extension(directory, extension):"""获取特定扩展名的文件:列出目录中指定类型的文件"""import osfiles = []for file in os.listdir(directory):  # 遍历目录if file.endswith(extension):  # 检查扩展名files.append(os.path.join(directory, file))  # 添加完整路径return files@staticmethoddef get_file_creation_time(file_path):"""获取文件创建时间:返回文件的创建时间戳转换后的日期"""import osimport datetimecreation_time = os.path.getctime(file_path)  # 获取创建时间戳return datetime.datetime.fromtimestamp(creation_time)  # 转换为可读格式

六、方法类型选择决策流程

以下是一个简单的决策流程,帮助你选择合适的方法类型:

  1. 问自己:这个方法需要访问或修改特定实例的状态吗?

    • 如果:使用实例方法
    • 如果:继续下一个问题
  2. 问自己:这个方法需要访问或修改类级别的状态吗?

    • 如果:使用类方法
    • 如果:继续下一个问题
  3. 问自己:这个方法在逻辑上属于这个类吗?

    • 如果:使用静态方法
    • 如果:考虑将其放到类外部作为常规函数,或放到更相关的类中

七、混合使用的实际案例

在实际项目中,通常会混合使用这三种方法类型:

class PaymentProcessor:# 类变量supported_providers = ["paypal", "stripe", "alipay"]transaction_count = 0def __init__(self, provider, api_key):if not PaymentProcessor.is_supported_provider(provider):raise ValueError(f"不支持的支付提供商: {provider}")self.provider = providerself.api_key = api_keyself.transactions = []# 实例方法:操作特定处理器的状态def process_payment(self, amount, currency, description):"""处理支付"""if not self.is_valid_amount(amount):raise ValueError("无效的支付金额")# 生成交易IDtransaction_id = PaymentProcessor.generate_transaction_id()# 处理支付逻辑(简化示例)transaction = {"id": transaction_id,"amount": amount,"currency": currency,"description": description,"provider": self.provider,"status": "completed","timestamp": PaymentProcessor.get_current_timestamp()}self.transactions.append(transaction)PaymentProcessor.transaction_count += 1return transaction_iddef get_transaction_history(self):"""获取处理器的交易历史"""return self.transactions# 类方法:操作类状态或创建实例@classmethoddef add_provider(cls, provider):"""添加新的支付提供商"""if provider not in cls.supported_providers:cls.supported_providers.append(provider)return Truereturn False@classmethoddef get_transaction_count(cls):"""获取总交易数"""return cls.transaction_count@classmethoddef create_paypal_processor(cls, api_key):"""创建PayPal处理器的便捷方法"""return cls("paypal", api_key)@classmethoddef create_stripe_processor(cls, api_key):"""创建Stripe处理器的便捷方法"""return cls("stripe", api_key)# 静态方法:辅助功能@staticmethoddef is_supported_provider(provider):"""检查提供商是否受支持"""return provider in PaymentProcessor.supported_providers@staticmethoddef is_valid_amount(amount):"""验证金额是否有效"""return isinstance(amount, (int, float)) and amount > 0@staticmethoddef generate_transaction_id():"""生成唯一交易ID"""import uuidreturn str(uuid.uuid4())@staticmethoddef get_current_timestamp():"""获取当前时间戳"""import timereturn int(time.time())@staticmethoddef format_currency(amount, currency):"""格式化货币显示"""currency_symbols = {"USD": "$", "EUR": "€", "GBP": "£", "JPY": "¥", "CNY": "¥", "RUB": "₽"}symbol = currency_symbols.get(currency, currency)return f"{symbol}{amount:.2f}"

八、总结

使用实例方法的情况:

  • 需要访问或修改实例的属性
  • 方法表示对象的行为或状态变化
  • 方法需要操作特定实例的数据
  • 方法在不同实例间表现出不同行为

使用类方法的情况:

  • 需要访问或修改类变量
  • 实现替代构造函数(工厂方法)
  • 方法涉及到所有类实例的共同逻辑
  • 在继承体系中需要感知调用方法的具体类

使用静态方法的情况:

  • 方法不需要访问实例或类的状态
  • 提供与类主题相关的辅助功能
  • 实现工具函数,但在逻辑上属于这个类
  • 方法是纯函数,输入相同则输出相同

选择恰当的方法类型不仅能使代码更加清晰,还能更准确地表达方法的意图和功能范围,从而提高代码的可读性和可维护性。理解这三种方法类型的区别和适用场景,是掌握Python面向对象编程的重要一步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/83506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

业务中台-典型技术栈选型(微服务、容器编排、分布式数据库、消息队列、服务监控、低代码等)

在企业数字化中台建设中&#xff0c;业务中台是核心支撑平台&#xff0c;旨在通过技术手段将企业核心业务能力抽象、标准化和复用&#xff0c;以快速响应前端业务需求。其核心技术流涉及从业务抽象到服务化、治理和持续优化的全流程。以下是业务中台建设中的核心技术体系及关键…

期望是什么:(无数次的均值,结合概率)21/6=3.5

https://seeing-theory.brown.edu/basic-probability/cn.html 期望是什么:(无数次的均值,结合概率)21/6=3.5 一、期望(数学概念) 在概率论和统计学中,**期望(Expectation)**是一个核心概念,用于描述随机变量的长期平均取值,反映随机变量取值的集中趋势。 (一…

matlab官方免费下载安装超详细教程2025最新matlab安装教程(MATLAB R2024b)

文章目录 准备工作MATLAB R2024b 安装包获取详细安装步骤1. 文件准备2. 启动安装程序3. 配置安装选项4. 选择许可证文件5. 设置安装位置6. 选择组件7. 开始安装8. 完成辅助设置 常见问题解决启动失败问题 结语 准备工作 本教程将帮助你快速掌握MATLAB R2024b的安装技巧&#x…

第3章 自动化测试:从单元测试到硬件在环(HIL)

在前两章中,我们已完成从环境搭建到流水线编译的自动化配置。为了真正保障软件质量、降低回归风险,本章将聚焦测试自动化,涵盖从最基础的单元测试,到集成测试,再到硬件在环(Hardware-in-the-Loop, HIL)测试的全流程。通过脚本驱动、测试报告可视化和与 CI 平台深度集成,…

信息收集+初步漏洞打点

目标&#xff1a;理解信息收集在渗透测试中的意义&#xff0c;熟悉常用工具用法&#xff0c;完成基本打点测试 一.理论学习&#xff1a; 模块内容说明信息收集分类主动信息收集 vs 被动信息收集目标发现子域名、IP、端口、子站点、目录、接口技术指纹识别Web框架&#xff08;如…

uniapp+vue3开发项目之引入vuex状态管理工具

前言&#xff1a; 我们在vue2的时候常用的状态管理工具就是vuex&#xff0c;vue3开发以后&#xff0c;又多了一个pinia的选项&#xff0c;相对更轻便&#xff0c;但是vuex也用的非常多的&#xff0c;这里简单说下在uni-app中vuex的使用。 实现步骤&#xff1a; 1、安装&#x…

浅谈“量子计算应用:从基础原理到行业破局”

量子计算应用:从基础原理到行业破局 引言:量子计算为何成为科技革命新引擎? 量子计算利用量子力学原理(叠加态、纠缠态、量子干涉)突破经典计算的极限,在特定领域可实现指数级加速。根据中研普华预测,2025年全球量子计算市场规模将突破80亿美元,2035年可达8117亿美元。…

UNiAPP地区选择

<template> <view class"container"> <!-- 左侧地区列表 --> <scroll-view class"left-list" scroll-y :scroll-into-view"currentLetterId" scroll-with-animation scroll"…

嵌入式硬件篇---CAN

文章目录 前言1. CAN协议基础1.1 物理层特性差分信号线终端电阻通信速率总线拓扑 1.2 帧类型1.3 数据帧格式 2. STM32F103RCT6的CAN硬件配置2.1 硬件连接2.2 CubeMX配置启用CAN1模式波特率引脚分配过滤器配置&#xff08;可选&#xff09; 3. HAL库代码实现3.1 CAN初始化3.2 发…

DeepSeek-R1 Supervised finetuning and reinforcement learning (SFT + RL)

DeepSeek-R1Supervised finetuning and reinforcement learning (SFT RL) 好啊&#xff0c;我们今天的直播会非常透彻的跟大家系统性的分享一下整个agents AI就大模型智能体系统和应用程序。我们在做开发的时候&#xff0c;或者实际做企业级的产品落地的时候&#xff0c;你必…

机器学习 day04

文章目录 前言一、线性回归的基本概念二、损失函数三、最小二乘法 前言 通过今天的学习&#xff0c;我掌握了机器学习中的线性回归的相关基本概念&#xff0c;包括损失函数的概念&#xff0c;最小二乘法的理论与算法实现。 一、线性回归的基本概念 要理解什么是线性回归&…

img.dims() <= 2 in function ‘cv::matchTemplate报错

Mat src mat_ori;//imread(img_original);Mat src_template imread(img_template);cvtColor(src, src, COLOR_BGR2RGB);//不转换&#xff0c;matchTemplate将报错cvtColor(src_template, src_template,COLOR_BGR2RGB);//不转换&#xff0c;matchTemplate将报错 error: (-215…

NY321NY322美光闪存芯片NY323NY336

NY321NY322美光闪存芯片NY323NY336 在存储技术飞速发展的今天&#xff0c;美光科技的闪存芯片凭借其创新架构与高性能表现&#xff0c;已成为工业自动化、智能终端等领域的核心组件。本文将围绕技术解析、产品评测、行业趋势、应用案例及市场动态五大维度&#xff0c;深入探讨…

exit耗时高

背景&#xff1a;程序退出发现被强制退出&#xff0c;而不是正常的退出。正常退出是发送15信号&#xff0c;而异常退出是发送信号9&#xff0c;强制退出。退出机制是先发送信号15&#xff0c;然后6s内没有退出完成&#xff0c;会发送信号9。通过查看退出流程&#xff0c;是将初…

docker compose up -d 是一个用于 通过 Docker Compose 在后台启动多容器应用 的命令

docker compose 表示调用 Docker Compose 工具&#xff0c;用于管理基于 YAML 文件定义的多容器应用。 up 核心指令&#xff0c;作用是根据 docker-compose.yml 文件中的配置&#xff0c;创建并启动所有定义的服务、网络、卷等资源。 如果容器未创建&#xff0c;会先构建镜像&…

从辅助到协作:GitHub Copilot的进化之路

如果说现代程序员的标配工具除了VS Code、Stack Overflow之外&#xff0c;还有谁能入选&#xff0c;那一定是GitHub Copilot。从2021年首次亮相&#xff0c;到如今深度集成进开发者日常流程&#xff0c;这个“AI编程助手”已经不只是写几行自动补全代码的小帮手了&#xff0c;而…

局部放大maya的视图HUD文字大小的方法

一、问题描述&#xff1a; 有网友问&#xff1a;有办法局部放大maya的字体吗比如hud中currenttime打开之后画面右下角有个frame 想放大一下能做到吗&#xff1f; 在 Maya 中&#xff0c;可以通过自定义 HUD&#xff08;Heads-Up Display&#xff09;元素的字体大小来局部放大特…

C++中隐式的类类型转换知识详解和注意事项

一、隐式转换的基本概念 隐式类型转换&#xff08;implicit conversion&#xff09;指编译器在需要时自动在两种类型之间插入转换代码&#xff0c;无需显式调用。对于内置类型&#xff08;如 int 到 double&#xff09;&#xff0c;转换由标准定义&#xff1b;对于用户自定义类…

【C++】18.二叉搜索树

由于map和set的底层是红黑树&#xff0c;同时后面要讲的AVL树(高度平衡二叉搜索树)&#xff0c;为了方便理解&#xff0c;我们先来讲解二叉搜索树&#xff0c;因为红黑树和AVL树都是在二叉搜索树的前提下实现的 在之前的C语言数据结构章节中&#xff0c;我们讲过二叉树&#x…

Leaflet使用SVG创建动态Legend

接前一篇文章&#xff0c;前一篇文章我们使用 SVG 创建了带有动态文字的图标&#xff0c;今天再看看怎样在地图上根据动态图标生成相关的legend&#xff0c;当然这里也还是使用了 SVG 来生成相关颜色的 legend。 看下面的代码&#xff0c;生成了一个 svg 节点&#xff0c;其中…