Python | 第十三章 | 多态 | 魔术方法 | 静态方法 | 抽象类
P130 多态练习题(1)2025/2/21
一、isinstance函数
- 基本说明:
isinstance()
用于判断对象是否为某个类或其子类的对象- 基本语法:
isinstance(object,classinfo)
- 解读形参:
object
:对象
classinfo
:可以是类名、基本类型或者由它们组成的元组
- 实例演示:
# @Author :ZH_JC
# @File :20_isinstance_example.py
# @Time :2025/2/21 14:01class AA:passclass BB(AA):passclass CC:pass# 创建两个对象
obj = BB()
obj2 = AA()# 分析输出的结果
print(f"obj 是不是BB的对象 {isinstance(obj, BB)}") # T
print(f"obj 是不是AA的对象 {isinstance(obj, AA)}") # T
print(f"obj 是不是CC的对象{isinstance(obj, CC)}") # Fnum = 9
print(f"num 是不是int:{isinstance(num, int)}") # T
print(f"num 是不是str:{isinstance(num, str)}") # F# 是元组中的一个返回 True
print(f"num 是不是str/int/list:{isinstance(num, (str, int, list))}") # T
二、练习题
- 代码阅读题,看下面的代码,分析输出内容是什么?
# @Author :ZH_JC
# @File :21_poly_exercise01.py
# @Time :2025/2/21 14:11class A:i = 10def sum(self):return self.getI()+ 10def sum1(self):return self.i + 10def getI(self):return self.iclass B(A):i= 20def sum(self):return self.i + 20def getI(self):return self.ib = B()
print(b.sum()) # 输出什么? 40
print(b.sum1()) # 输出什么 30
- 对上面的代码做修改(将B中sum注释),分析输出内容是什么?
- 知识点:当调用用对象成员的时候,会和对象本身动态关联
class A:i = 10def sum(self):# 这里的self是A还是B 【B】# 当调用用对象成员的时候,会和对象本身动态关联;所以会调用B里面的getIreturn self.getI()+ 10def sum1(self):# 这里B传进来依然是B里面的ireturn self.i + 10def getI(self):return self.iclass B(A):i= 20# def sum(self):# return self.i + 20def getI(self):return self.ib = B()
print(b.sum()) # 输出什么?-->30
print(b.sum1()) # 输出什么---> 30
P131 多态练习题(2)2025/2/22
一、练习题
编程题:
- 定义员工类
Employee
,包含私有属性(姓名和月工资),以及计算年工资get_annual
的方法- 普通员工
(Worker)
和经理(Manager)
继承员工类,经理类多了奖金bonus属性和管理manage方法,普通员工类多了work方法,普通员工和经理类要求根据需要重写get_annual
方法- 编写函数
show_emp_annual(e:Employee)
,实现获取任何员工对象的年工资- 编写函数
working(e:Emplovee)
,如果是普通员工,则调用work方法,如果是经理,则调用manage方法
# @Author :ZH_JC
# @File :22_poly_exercise02.py
# @Time :2025/2/22 15:05# 3、编程题(文件:poly_exercise_02.py)5min
# 1)定义员工类Employee,包含私有属性(姓名和月工资),以及计算年工资get_annual的方法
# 2)普通员工(Worker)和经理(Manager)继承员工类,经理类多了奖金bonus属性和管理manage方法,普通员工
# 类多了work方法,普通员工和经理类要求根据需要重写get annual方法
# 3)编写函数show_emp_annual(e:Employee),实现获取任何员工对象的年工资
# 4)编写函数working(e:Emplovee),如果是普通员工,则调用work方法,如果是经理,则调用manage方法class Employee:__name = None__salary = None# 构造器def __init__(self, name, salary):self.__name = nameself.__salary = salary# 计算年工资的方法def get_annual(self):return self.__salary * 12# 编写set_xxx和get_xxx方法def set_name(self, name):self.__name = namedef get_name(self):return self.__namedef set_salary(self, salary):self.__salary = salarydef get_salary(self):return self.__salary# 子类Worker
class Worker(Employee):def work(self):print(f"普通工人{self.get_name()} 正在工作...")# 子类Manager
class Manager(Employee):__bonus = Nonedef __init__(self, name, salary, bonus):super().__init__(name, salary)self.__bonus = bonusdef manager(self):print(f"经理{self.get_name()} 正在管理...")# 根据需要,经理有奖金,需要重写get_annualdef get_annual(self):# 这里必须使用super()调用父类annual,因为本类有了get_annual,否则会递归return super().get_annual() + self.__bonus# 3)编写函数show_emp_annual(e:Employee),实现获取任何员工对象的年工资
def show_emp_annual(e: Employee):print(f"{e.get_name()}的年工资是{e.get_annual()}")# 测试worker = Worker("king", 10000)
show_emp_annual(worker)manager = Manager("tim", 20000, 100000)
show_emp_annual(manager)# 4)编写函数working(e:Emplovee),如果是普通员工,则调用work方法,如果是经理,则调用manage方法
def working(e: Employee):# 如果是普通员工if isinstance(e, Worker):e.work()elif isinstance(e, Manager):e.manager()else:print("无法确定工作状态")working(worker)
working(manager)
总结:又涉及了封装继承和多态
P132 魔术方法 2025/2/22
- 参考文档:https://docs.python.org/zh-cn/3.12/reference/datamodel.html?highlight=_%20ne#basic-customization
一、基本介绍
- 什么是魔术方法:
- 在Python中,所有以双下划线包起来的方法,统称为
Magic Method
(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行。 - 魔术方法在类或对象的某些事件发生时会自动执行,让类具有神奇的"魔力"。如果希望根据自己的程序定制特殊功能的类,那么就需要对这些方法进行重写。
- Python中常用的运算符、for循环、以及类操作等都是运行在魔术方法之上的。
- 常见的魔术方法:
二、常见魔术方法
- 1、
__str__
基本介绍:
- 打印对象默认返回:类型名+对象内存地址【演示】,子类往往重写
__str__
,用于返回对象的属性信息
main__.Person object at 0x0000019314BC7C90>
- 重写
__str__
方法,print(对象)或str(对象)时,都会自动调用该对象的__str__
# @Author :ZH_JC # @File :23_str_magic_method.py # @Time :2025/2/22 17:32class Monster:name = Noneage = Nonegender = Nonedef __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = gender# 请输出Monster[name,job,sal]对象的属性信息# 可以根据需要重写__str__ :(如果不重写就是调用父类str的方法)"""说明:1. 在默认情况下,调用的是父类object的__str__2. 父类object的__str__返回的就是类型+地址3. __str___可以根据需要重写"""def __str__(self):return f"{self.name} {self.age} {self.gender}"m = Monster("青牛怪", 500, "男")# print(m,hex(id(m))) print(m) # 默认输出类型+对象的地址
- 2、
__eq__
基本介绍:
==
是一个比较运算符:对象之间进行比较时,比较的是内存地址是否相等,即判断是不是同一个对象- 重写
__eq__
方法,可以用于判断对象内容/属性是否相等
- 应用实例:
1)判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样,则返回true,反之false
2)Person类,属性(name,age,gender)# @Author :ZH_JC # @File :24_eq_magic_method.py # @Time :2025/2/22 19:06class Dog:def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = genderclass Person:def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = gender# 判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样,# 则返回true,反之falsedef __eq__(self, other): # other 相当于比较时的p2# 判断other是不是Person (人和狗比不合理,不正常比较)if isinstance(other, Person):return (self.name == other.name andself.age == other.age andself.gender == other.gender)return False# 没有重写 __eq__ 前,== 比较的是内存地址,返回F,重写后返回Tp1 = Person("smith", 20, "男") p2 = Person("smith", 21, "男") dog = Dog("smith", 20, "男")# ==比较的是内存地址,所以返回的是False print(f"p1==p2: {p1 == p2}") # F print(f"p1==dog: {p1 == dog}") # F
三、其他魔术方法
- 应用实例:
- 根据Person对象的年龄进行比较大小,重写相应的魔术方法
- Person类,属性
(name,age,gender
class Person:def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = gender# 判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样,# 则返回true,反之falsedef __eq__(self, other): # other 相当于比较时的p2# 判断other是不是Person (人和狗比不合理,不正常比较)if isinstance(other, Person):return (self.name == other.name andself.age == other.age andself.gender == other.gender)return False# 重写__lt__def __lt__(self,other):# 判断other是不是Person (人和狗比不合理,不正常比较)if isinstance(other, Person):return self.age < other.agereturn "类型不一致"# 重写__le__def __le__(self,other):# 判断other是不是Person (人和狗比不合理,不正常比较)if isinstance(other, Person):return self.age <= other.agereturn "类型不一致"def __ne__(self, other): # other 相当于比较时的p2return not self.__eq__(other)# 没有重写 __eq__ 前,== 比较的是内存地址,重写是比较属性内容p1 = Person("smith", 21, "男")
p2 = Person("smith", 21, "男")
dog = Dog("smith", 20, "男")# ==比较的是内存地址,所以返回的是False
print(f"p1==p2: {p1 == p2}")
print(f"p1==dog: {p1 == dog}")print(f"p1 < p2:{p1 < p2}")
print(f"p1 < p2:{p1 <= p2}")
print(f"p1 < p2:{p1 != p2}")
P133 class对象和静态方法 2025/3/2
一、基本介绍
-
参考文档:https://docs.python.org/zh-cn/3.11/tutorial/classes.html#instance-objects
-
类本身也是对象,即:
Class对象
-
案例演示:
# @Author :zjc
# @File :25_class_object.py
# @Time :2025/3/2 20:51class Monster:name = "蝎子精"age = 300def hi(self):print(f"hi() {self.name}-{self.age} ")# 下一个断点,可以看到Monster的情况print(Monster)# 通过Class对象,可以引用属性〔没有创建实例对象也可以引用/访问)
print(f"Monster.name: {Monster.name} Monster.age:{Monster.age}")# 通过类名如何调用非静态成员方法.(类本身就是对象),通过类名也可以调用成员方法
Monster.hi(Monster)
二、静态方法
-
基本介绍:
- 参考文档:https://docs.python.org/zh-cn/3.12/library/functions.html#staticmethod
3. @staticmethod
将方法转换为静态方法
4. 静态方法不会接收隐式的第一个参数,要声明一个静态方法,语法:
class c:@staticmethoddef f(arg1, arg2, argN): ...
- 静态方法既可以由类调用(如
C.f())
,也可以由实例中调用(如C().f()
)
# @Author :zjc
# @File :26_staticmethod.py
# @Time :2025/3/2 21:17class Monster:name = "蝎子精"age = 300def hi(self):print(f"hi() {self.name}-{self.age} ")@staticmethoddef ok():print(f"ok()... ")# 不需要实例化,通过类即可调用静态方法
Monster.ok()# 通过实例对象,也可以调用静态方法
monster = Monster()
monster.ok()# 这样调用也是一样的
Monster().ok()
P134 抽象类快速入门 2025/3/3
一、问题引出
- 有行为,但是不明确。
class Animal:def __init__(self, name, age):self.name = nameself.age = agedef cry(self):"""动物都有叫唤的行为...但是这个行为不明确(即不能明确的实现..)::return: """print("不知道是什么动物,不知道是什么叫声...")
- 需求:
- 当父类的某些方法,需要声明,但是又不确定如何实现时,怎么办?
- 不需要实例化父类对象,父类主要的是用于设计和制定规范,让其它类来继承并实现,怎么办?
- 解决方案->抽象类
二、抽象类介绍
- 默认情况下,Python不提供抽象类,Python附带一个模块,该模块为定义抽象基类提供了基础,该模块名称为abc
- 当我们需要抽象基类时,让类继承ABC(abc模块的ABC类),使用
@abstractmethod
声明抽象方法(@abstractmethod
用于声明抽象方法的装饰器,在abc模块中),那么这个类就是抽象类 - 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类的抽象方法
三、快速入门
- 参考文档:https://docs.python.org/zh-cn/3.12/library/abc.html#abstractmetho、
- 当父类的一些方法不能确定时,可以使用
@abstractmethod
声明(说明:@abstractmethod
用于声明抽象方法的装饰器),同时继承ABC类,那么这个类就是抽象类 - 案例演示:我们看看如何把Animal做成抽象类,并让子类Tiger实现
# @Author :zjc
# @File :27_abstract_quick_start.py
# @Time :2025/3/3 14:22# 导入abc模块中的ABC类
from abc import ABC, abstractmethod# 把Animal做成抽象类,并让子类Tiger实现# Animal就是抽象类
class Animal(ABC):def __init__(self, name, age):self.name = nameself.age = age# 这时:cry就是一个抽象方法@abstractmethoddef cry(self):# """# 动物都有叫唤的行为...但是这个行为不明确(即不能明确的实现..):# :return:# """# print("不知道是什么动物,不知道是什么叫声...")pass# 注意:抽象类(含有抽象方法),不能实例化
# TypeError: Can't instantiate abstract class Animal
# animal = Animal("动物",3)# 编写子类Tiger 继承Animal 并实现抽象方法
class Tiger(Animal):def cry(self):print(f"老虎{self.name} 嗷嗷")# 因为Tiger继承了Animal,这里可以使用Animal的构造器
tiger = Tiger("皮皮", 2)
tiger.cry()
P135 抽象类细节和练习 2025/3/3
一、注意事项和细节
- 抽象类不能被实例化
- 抽象类需要继承ABC,并且需要至少一个抽象方法
# 抽象类需要继承ABC,并且需要至少一个抽象方法from abc import ABC, abstractmethodclass AAA(ABC):name = "tim"# 如果有一个抽象方法是不能被实例化的@abstractmethoddef f1(self):pass#如果没有一个抽象方法,能实例化..
obj1 = AAA()
print( "ok")
- 抽象类中可以有普通方法
from abc import ABC, abstractmethodclass AAA(ABC):name = "tim"@abstractmethoddef f1(self):passdef hi(self):print("hi()~~")def ok(self):passclass BBB(AAA):# 实现父类的f1抽象方法def f1(self):print("BBB-f1()...")# 全部执行成功说明,抽象类中可以有普通方法
obj2 = BBB()
obj2.f1()
obj2.hi()
obj2.ok()
print("~~~")
- 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,否则它仍然是一个抽象类
from abc import ABC, abstractmethodclass AAA(ABC):name = "tim"@abstractmethoddef f1(self):pass@abstractmethoddef f2(self):passdef hi(self):print("hi()...")def ok(self):passclass BBB(AAA):# 实现父类的f1抽象方法def f1(self):print("BBB-f1()...")# 如果没有完全实现AAA的抽象方法,则会报错# TypeError: Can't instantiate abstract classdef f2(self):print("BBB-f2()...")obj2 = BBB()
obj2.f1()
obj2.hi()
obj2.ok()
print("~~~")
二、练习题
- 代码:
# @Author :zjc
# @File :29_abstract_exercise.py
# @Time :2025/3/3 15:38
"""
1)编写一个Employee类,做成抽象基类,包含如下三个属性: name,id,salary,
提供必要的构造器和抽象方法;work()
2)对于Manager类来说,他既是员工,还具有奖金(bonus)的属性,
请使用继承的思想,设计CommonEmployee类和Manager类,要求实现work(),
提示"经理/普通员工名字工作中.…."
OOP继承+抽象类
"""
from abc import abstractmethod, ABC# 父类-抽象类
class Employee(ABC):def __init__(self, name, id, salary):self.name = nameself.id = idself.salary = salary@abstractmethoddef work(self):pass# 子类CommonEmployee,Manager
class CommonEmployee(Employee):def work(self):print(f"普通员工{self.name}工作中.….")class Manager(Employee):def __init__(self, name, id, salary, bonus):super().__init__(name, id, salary)self.bonus = bonusdef work(self):print(f"经理{self.name}工作中.….")# 测试:
manager = Manager("king", "1-111", 10000, 100000)
manager.work()commonemployee = CommonEmployee("tim","2-222",5000)
commonemployee.work()
P136 模板设计模式 2025/3/3
一、什么是设计模式
- 设计模式-简介:
- 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式
- 设计模式就像是经典的惯谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索
二、模板设计模式
-
基本介绍:
- 抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
-
模板设计模式能解决的问题:
- 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
- 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。
三、模板设计模式-最佳实践
-
开发需求:
- 有多个类,完成不同的任务job
- 要求统计得到各自完成任务的时间
- 请编程实现:
-
time.time()
: -
示意图:
- 优化-使用模板设计模式来解决:
- 设计一个抽象基类
(Template)
,能完成如下功能; - 编写方法
cal_time()
,可以计算某段代码的耗时时间 - 编写抽象方法
job()
- 编写一个子类,继承抽象类
Template
,并实现job
方法。 - 完成测试:
- 设计一个抽象基类
# @Author :zjc
# @File :30_模板设计模式.py
# @Time :2025/3/4 20:39# 1)有多个类,完成不同的任务job
# 2)要求统计得到各自完成任务的时间
# 3)请编程实现使用模板设计模式import time
from abc import abstractmethod, ABC# 抽象类-模板类
class Template(ABC):@abstractmethoddef job(self):pass# 统计任务执行时间def cal_time(self):# 得到开始的时间,豪秒数start = time.time() * 1000self.job()# 得到结束的时间,秒数end = time.time() * 1000print("计算任务执行时间", (end - start))class AA(Template):def job(self):num = 0for i in range(1, 800001):num += iclass BB(Template):def job(self):num = 1for i in range(1, 900001):num -= i# 测试, 引出模板设计
if __name__ == '__main__':aa = AA()aa.cal_time()bb = BB()bb.cal_time()
P137 本章练习题 2025/3/4
一、练习题
sort()
函数:
# @Author :zjc
# @File :32_homework01.py
# @Time :2025/3/4 21:26class Person:def __init__(self, name, age, job):self.name = nameself.age = ageself.job = jobdef __str__(self):return f"{self.name}--{self.age}--{self.job}"p1 = Person("smith", 20, "java工程师")
p2 = Person("king", 18, "学生")
p3 = Person("HSP", 26, "老师")my_list = [p1, p2, p3]for p in my_list:print(p)# 有3个person对象,并按照age 从大到小进行排斑
"""思路分析:1. 解决方案:冒泡排序=>根据需求做了改进2. 解决方案:直接使用列表的sort方法"""# 接收一个列表,里面的元素是Person对象
def bubble_sort(my_lsit: list[Person]):"""功能:对传入的列表排序-顺序从大到小(按照年龄):param my_lsit:传入的列表:return:无"""# i变量来控制多少轮排序lenfor i in range(0, len(my_lsit) - 1):for j in range(0, len(my_lsit) - 1 - i): # [0,1,2]# 如果前面的元素大于后面的元素就交换# 如果是从小到大是:>;从大到小 <if my_lsit[j].age < my_lsit[j + 1].age:my_lsit[j], my_lsit[j + 1] = my_lsit[j + 1], my_lsit[j]# 方法1.调用bubble
# bubble_sort(my_list)# 方法2:直接使用列表sort()
"""解读:1. key=lambda ele:ele.age 表示我指定按照列表元素的age属性进行排序将my_list的元素取出赋给ele,然后ele.age属性进行排序2. reverse=True就是从大到小
"""
my_list.sort(key=lambda ele:ele.age,reverse=True)print("排序后".center(32,"-"))# 再次遍历:
for p in my_list:print(p)
- 文件中有Grand , Father 和Son ,问:父类和子类中通过
self
和super()
都可以调用哪些属性和方法
# @Author :zjc
# @File :33_homework02.py
# @Time :2025/3/5 14:17class Grand:name = "AA"__age = 100def g1(self):print("Grand-g1()")class Father(Grand):id = "001"__score = Nonedef f1(self):# super()可以访问哪些成员(属性和方法)?# 填写?:super().name super().g1()# self可以访问哪些成员?# 填写?:self.name self.__score self.f1() self.name self.g1print("Father-f1()")class Son(Father):name = "BB"def g1(self):print("Son-g1()")def __show(self):print("Son-__show()")# super()可以访问哪些成员(属性和方法)?# 填写:super().id super().f1 super().name super().g1# self可以访问哪些成员?# 填写self.name self.g1() self.__show self.id self.f1()
- 编写Doctor类,属性:name, age, job, gender, sal, 5个参数的构造器,重写
__eq__()
方法。并判断测试类中创建的两个对象是否相等(相等就是判断属性是否相同)
# @Author :zjc
# @File :34_homework03.py
# @Time :2025/3/5 15:03# 编写Doctor类,属性:name, age, job, gender, sal,
# 5个参数的构造器,重写`__eq__()`方法。
# 并判断测试类中创建的两个对象是否相等(相等就是判断属性是否相同)class Doctor:def __init__(self, name, age, job, gender, sal):self.name = nameself.age = ageself.gender = genderself.sal = salself.job = job# 重写__eq__def __eq__(self, other):# 如果other类型不合适Doctor,直接返回Falseif not isinstance(other, Doctor):return False# 如果所有的属性都相同,则返回Truereturn (self.job == other.joband self.name == other.nameand self.age == other.ageand self.gender == other.genderand self.sal == other.sal)# 测试:
doctor1 = Doctor("king", 30, "牙科医生", "男", 10000)
doctor2 = Doctor("king", 20, "牙科医生", "男", 10000)print("doctor1 == doctor2", doctor2 == doctor1)
P138 本章小结 2025/3/5
一、小结
P139 出租系统需求和界面 2025/3/5
一、需求
-
项目需求说明:
- 实现基于文本界面的《房屋出租软件》
- 能够实现对房屋信息的添加、修改和删除,并能够打印房屋信息明细表
-
界面:
相关文章:
Python | 第十三章 | 多态 | 魔术方法 | 静态方法 | 抽象类
P130 多态练习题(1)2025/2/21 一、isinstance函数 基本说明: isinstance()用于判断对象是否为某个类或其子类的对象基本语法:isinstance(object,classinfo)解读形参: object:对象 classinfo:可以是类名、基本类型或者由它们组成…...
线程安全问题的原因与解决方案总结
目录 一 什么是线程安全? 二 线程安全问题的实例 三 线程安全问题的原因 1.多个线程修改共享数据 2.抢占式执行 3.修改操作不是原子的 4.内存可见性问题 5.指令重排序 四 解决方案 1.同步代码块 2.同步方法 3.加锁lock解决问题 一 什么是线程安全&…...
设计模式-模版方法
目录 什么是模版方法? 怎么理解抽象类的算法骨架? Burn功能骨架 战士类 法师类 什么是模版方法? 借助抽象类定义算法的骨架,再由具体子类实现算法的特定步骤。这种设计模式让算法的整体结构得以固定,同时又能让不…...
c# 运用策略模式与模板方法模式实例
策略模式 策略模式的核心在于定义一系列算法,把它们封装起来,并且让它们能够相互替换。策略模式让算法的变化独立于使用算法的客户端。在这个方法里,策略模式的体现如下: convertFunc 参数:这是一个委托类型的参数&a…...
基于51单片机的3路温度报警器proteus仿真
地址: https://pan.baidu.com/s/1qrCpGuzZRbeFVVjaGMffQA 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C51 是一款常用的 8 位单片机,由 Atmel 公司(现已被 Microchip 收…...
llama-factory微调qwen2.5-vl
本文不生产技术,只做技术的搬运工!!! 前言 目前大模型百花齐放,微调方法复杂多样,且教程复杂,工程端想要进行垂域模型适配困难重重,本篇博客详细介绍了qwen2.5-vl的全流程微调过程,包括环境配置、数据集制作、模型训练、模型导出、模型部署、模型推理等过程,希望对工…...
淘宝历史价格采集合规指南:官方 API + 轻量爬虫混合方案
在电商数据分析领域,获取淘宝商品的历史价格数据对于企业制定价格策略、进行竞品分析以及消费者洞察市场价格波动趋势都具有重要意义。然而,由于淘宝平台对数据安全和合规性的严格要求,历史价格采集工作需要在合法合规的框架内进行。本文将详…...
文档控件DevExpress Office File API v24.2亮点:不再支持非Windows系统
DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库,不用安装Microsoft Office,就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…...
TDengine.C/C++ 连接器
简介 C/C 开发人员可以使用 TDengine 的客户端驱动,即 C/C 连接器(以下都用 TDengine 客户端驱动表示),开发自己的应用来连接 TDengine 集群完成数据存储、查询以及其他功能。TDengine 客户端驱动的 API 类似于 MySQL 的 C API。…...
什么是混合搜索Hybrid Search?
🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创AI未来! 🚀 混合搜索通常指一种结合多种搜索方法或技术的搜索策略,旨在提供更…...
滤波器:模拟滤波器和数字滤波器的区别
滤波器是一种用于从信号中去除不需要的频率成分,只保留所需频率成分的电子设备或算法。根据实现方式的不同,滤波器主要分为模拟滤波器和数字滤波器两大类。以下是对这两种滤波器的详细比较: 一、实现方式与原理 模拟滤波器 实现方式…...
AudioRecord 录制pcm转wav
pcm转wav PCM 格式校验pcm 添加 wav 头信息WAVWAV 格式检验小端序? 参考地址 PCM 格式校验 /*** 专业PCM文件验证(支持动态参数与多格式)* param silenceThreshold 静音检测阈值(0.0~1.0),默认90%零值为静…...
625SJBH网上便利店的设计与实现
1前 言 目前,网络正以一种前所未有的冲击力在影响着人类的活动,包括人类的生产和日常生活。网络的诞生和发展,颠覆了传统的信息传播方式,冲破了存在于传统交流方式中时间和空间的种种壁垒,极大地改变了人类从物质到精…...
如何开发英语在线训练小程序:从0到1的详细步骤
在数字化学习的浪潮下,英语在线训练小程序凭借便捷、高效的学习模式,成为众多英语学习者的得力助手。如果你也想开发一款独具特色的英语在线训练小程序,不妨参考以下步骤,开启你的小程序开发之旅。 一、前期规划 (…...
java设计模式-装饰者模式
装饰者模式(Decorator) 定义 1、动态的将新功能附加到对象上,在对象功能扩展方面,他比继承更有弹性,也体现了开闭原则(OCP) 2、这里提到的动态的将新功能附加到对象和OCP原则,在后面应用实际上会以代码的形式体现。 //饮料 // 饮…...
我提了一个 Androidx IssueTracker
问题 在运行 gradle plugin 插件的 transform R8 阶段出现了报错 Caused by: com.android.tools.r8.internal.xk: java.lang.NullPointerException: Cannot invoke “String.length()” because “” is null 报错日志 FAILURE: Build failed with an exception.* What went w…...
spring mvc @ResponseBody 注解转换为 JSON 的原理与实现详解
ResponseBody 注解转换为 JSON 的原理与实现详解 1. 核心作用 ResponseBody 是 Spring MVC 的一个注解,用于将方法返回的对象直接序列化为 HTTP 响应体(如 JSON 或 XML),而不是通过视图解析器渲染为视图(如 HTML&…...
RK3588芯片NPU的使用:Windows11 Docker中运行MobileNet模型以及部署到开发板进行目标检测
本文的目标 本文将在RKNN Docker环境(见本系列的第二篇文章)中练习MobileNet图像分类示例,并通过adb工具部署到RK3588开发板。 MobileNet简介请参考上一篇文章。 开发环境说明 主机系统:Windows11目标设备:搭载RK35…...
智能仓储数字孪生Demo(Unity实现)
一、项目背景与行业痛点 医药流通行业仓储管理面临三大核心挑战: 合规性风险:GSP(药品经营质量管理规范)对温湿度、药品批次追溯的严苛要求,传统人工记录易出错效率瓶颈:库区布局复杂,人工巡检…...
Qt上hook钩子的使用,监测键盘和鼠标。
演示平台:windows。 编译环境:Qt5.12.2 MinGW 64-bit Windows API: ///加载钩子 /*** SetWindowsHookEx 函数解释* int idHook 所监控的挂钩类型* HOOKPROC lpfn 监控信息的处理函数* HINSTANCEhMod 监控信息的动态链接位置 nullptr则与本线…...
Android12源码编译之预置Android Studio项目Android.mk文件编写
1、在AndroidManifest.xml文件中添加package"com.sprd.silentinstalldemo"属性,因为新版本的Android Studio默认生成的AndroidManifest.xml是没有这个属性值的 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:an…...
微服务注册中心选择指南:Eureka vs Consul vs Zookeeper vs Nacos
文章目录 引言微服务注册中心概述什么是服务注册与发现选择注册中心的标准 常见的微服务注册中心1. Eureka1.1 理论基础1.2 特点1.3 示例代码 2. Consul2.1 理论基础2.2 特点2.3 示例代码 3. Zookeeper3.1 理论基础3.2 特点3.3 示例代码 4. Nacos4.1 理论基础4.2 特点4.3 示例代…...
pg_waldump无法定位WAL文件问题
目录 排查pg_waldump无法定位WAL文件问题的步骤1. 确认WAL文件路径配置2. 检查WAL文件名格式3. 验证文件存在性4. 检查文件权限5. 时间线历史文件检查6. 使用pg_controldata验证状态7. 尝试指定完整路径 典型错误场景及解决方案 排查pg_waldump无法定位WAL文件问题的步骤 1. 确…...
Mysql安装
Mysql安装 1. windows安装1.1 官网下载1.2 安装 1. windows安装 1.1 官网下载 官网下载 选择对于版本,然后跳转到下载页 1.2 安装...
Windows版-RabbitMQ自动化部署
一键完成Erlang环境变量配置(ERLANG_HOME系统变量) 一键完成RabbitMQ环境变量配置(RabbitMQ系统变量) 实现快速安装部署RabbitMQ PS: 需提前下载安装: - otp_win64_25.0.exe (Erlang) - rabbit…...
spring mvc的拦截器HandlerInterceptor 接口详解
HandlerInterceptor 接口详解 1. 接口方法说明 方法作用执行时机返回值/注意事项preHandle请求处理前拦截在控制器方法执行前调用返回 false 中断后续流程;返回 true 继续执行postHandle控制器方法执行后拦截在控制器方法返回结果后,视图渲染前调用无返…...
Linux平台内存泄漏检测工具介绍: ASan vs Valgrind
目录: 前言Valgrind 介绍在Ubuntu上安装Valgrind 核心主要功能Valgrind 基本用法1. --leak-checkfull2. --show-leak-kindsall3. --track-originsyes4. 其他常用选项--tool<name>--log-file<filename>-v / --verbose--error-exitcode<n> 示例命令…...
c# 数据结构 链表篇 有关单链表的一切
本人能力有限,本文仅作学习交流与参考,如有不足还请斧正 目录 0.单链表好处 0.5.单链表分类 1.无虚拟头节点情况 图示: 代码: 头插/尾插 删除 搜索 遍历全部 测试代码: 全部代码 2.有尾指针情况 尾插 全部代码 3.有虚拟头节点情况 全部代码 4.循环单链表 几个…...
二叉树层平均值:层序遍历+队列解法详解
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[3.00000,14.50000,11.00000] 解释:第 0 层的平均值为 …...
解决 Docker Swarm 集群节点故障:从问题剖析到修复实战
解决 Docker Swarm 集群节点故障:从问题剖析到修复实战 在使用 Docker Swarm 构建容器编排集群时,可能会遭遇各种难题。本文将分享一次处理 Docker Swarm 集群节点故障的实战经历,涵盖问题出现的缘由、详细剖析以及完整的解决步骤࿰…...
【Java中级】11章、注解、元注解介绍、快速入门,了解java注解的基本使用方式【2】
文章内容 JDK内置的基本注释类型 Override DeprecatedSuppressWarnings 元注解 对注释进行注解 ❤️内容涉及注解的定义,快速入门,注意事项 🌈 跟着B站一位老师学习的内部类内容,现写这篇文章为学习内部类的小伙伴提供思路支持&…...
Qt中自定义插件和库(1)
Qt中自定义插件和库(1) 在Qt中自定义插件和库的方法有两种: 1.提升法。 2.自定义Qt Designer 插件法。 下面就以《Qt 5.9 C开发指南》一书中的例子来讲解。下面先讲提升法。 一、提升法 提升法(Promotion)是Qt Designer中重用自定义控件的一种方法,…...
RK3568下QT实现视频播放器
在开发多媒体应用时,视频播放器是常见的项目。QT 作为一款跨平台的 C++ 应用程序开发框架,凭借丰富的类库和工具,让开发视频播放器变得简单。本文将介绍如何使用 QT 的QMediaPlayer和QVideoWidget类,实现一个简单的视频播放器,并逐步添加打开视频、播放、暂停、停止以及进…...
Shell脚本核心要点总结
刷题: Shell脚本核心要点总结 一、Shell基础 定义:Shell是用户与内核交互的接口,本质是多个指令的集合,需遵循逻辑关系。类型: 编译型语言(如C):需编译器(如gcc…...
C++-FFmpeg-(5)-1-ffmpeg原理-ffmpeg编码接口-AVFrame-AVPacket-最简单demo
1.视频编码原理 2.FFMpeg编码接口和AVPacket结构体详解 2.1ffmpeg编码接口 -编码器上下文 2.2AVPacket结构体 2.3AVFrame结构体 3.视频播放最简单demo 3.1FFMpeg编码器获取和上下文打开 3.2视频帧创建和测试 1.视频编码原理 1.1 流程:像素格式转换-&…...
Opencv计算机视觉编程攻略-第十二节 处理视频序列
视频由一系列图像构成,这些图像称为帧,帧是以固定时间间隔获取的(称为帧速率,通常用帧/秒表示,例如大疆无人机抽取每一帧),本文将介绍如何读取、处理和存储视频序列。如果从视频序列中提取出独立…...
浮点许可优化管理软件 - 智能许可管理专家
为什么选择浮点许可优化管理软件? 在当今数字化时代,企业软件许可支出持续攀升,如何实现许可资源的最优配置成为一大挑战。浮点许可优化管理软件通过先进的算法和自动化技术,帮助企业实现许可资源的精准管理和成本优化。 革命性的智能化功能…...
Spring Boot接口返回Long类型的数据时丢失精度的全局处理
1、问题 当实体类中的字段为Long类型时,通过Ajax请求返回给前段,在js中数据会丢失精度 直接通过postman请求或通过浏览器请求,看下响应则不会丢失精度 2、处理方式 1、使用JsonSerialize注解 JsonSerialize(using ToStringSerializer.…...
量子计算入门:开启未来计算的次元之门
在科幻电影中,我们常看到“量子计算机”被描绘成无所不能的黑科技——破解密码、模拟宇宙、瞬间完成超算百年的任务。但现实中,量子计算究竟是什么?它真的能颠覆传统计算机吗? 一、从“硬币”到“薛定谔的猫”:量子世界…...
学习日志37—基于变分量子电路的量子机器学习算法综述
基于变分量子电路的量子机器学习算法综述 论文原链接参考:https://crad.ict.ac.cn/article/cstr/32373.14.issn1000-1239.202330979 这篇综述的核心内容是基于变分量子电路(VQCs)的量子机器学习算法的研究现状、应用进展以及面临的挑战和未…...
初入Web网页开发
1、网页哪些内容 1.1 三个核心文件的作用 index.html:网页的骨架,用HTML编写网页结构和内容。 script.js:网页的行为,用JavaScript实现交互功能(如按钮点击事件)。 styles.css:网页的外观&…...
Vue进行前端开发流程
一、创建vue项目 创建vue项目:先进入要操作的目录下,注意本项目是用vue2开发的。 vue create vue项目名 二、项目开发 1.创建项目结构 2.开发功能模块 主入口App.vue <template><div class"boss-app"><Header /><m…...
【深度学习:实战篇】--PyTorch+Transformer谣言检测系统
任务:构建一个多模态谣言检测模型。 数据集描述如下: 数据集包含以下模态: 谣言文本:谣言的核心文本信息。2. 配图:与谣言文本相关的图像数据;3. OCR 文本:可以通过 PaddleOCR 从配图中提取的…...
PostGreSQL/openGauss表膨胀处理
如果面试官问你,Oracle与PG/OG最大的区别是什么?你要是没回答出MVCC机制,表膨胀,那你多半挂了。 在PG/OG数据库中,命令vacuum full,插件pg_repack用于处理表膨胀,但是别高兴得太早,如…...
视频融合平台EasyCVR搭建智慧粮仓系统:为粮仓管理赋能新优势
一、项目背景 当前粮仓管理大多仍处于原始人力监管或初步信息化监管阶段。部分地区虽采用了简单的传感监测设备,仍需大量人力的配合,这不仅难以全面监控粮仓复杂的环境,还容易出现管理 “盲区”,无法实现精细化的管理。而一套先进…...
基于 Node.js 和 Spring Boot 的 RSA 加密登录实践
在当今的互联网应用开发中,用户数据的安全性至关重要。登录功能作为用户进入系统的第一道防线,其安全性更是不容忽视。本文将介绍一种基于 RSA 加密的登录方案,前端使用 Node.js 的 node-forge 库对密码进行公钥加密,后端使用 Spr…...
jupyter在Pycharm中遇到的一个问题
jupyter比较简洁,可以分块执行,下面显示结果,还能用Markdown写注释,总体来说来还是比较好用的。 但是遇到了一个奇怪的问题,从一个py文件中导入一个函数,结果输出为None。但是如果直接把这个函数的内容复制…...
十二、buildroot系统 adb登录权限设置
4.6.4、adb权限设置 android-adbd 是 ADB(Android Debug Bridge)的守护进程,允许开发者远程访问和调试设备。它通常用于 Android 设备,但在嵌入式 Linux上,也可以用来提供远程 shell、文件传输和应用调试功能。 …...
MySQL、Oracle 和 PostgreSQL 是三种主流的关系型数据库的主要原理性差异分析
MySQL、Oracle 和 PostgreSQL 是三种主流的关系型数据库,它们在底层原理和设计哲学上存在显著差异,尤其在存储引擎、事务处理、并发控制、索引结构、复制机制等方面。以下是它们的主要原理性差异分析: 1. 存储引擎与架构设计 MySQL 多存储引…...
【AI开源大模型工具链ModelEngine】【01】应用框架-源码编译运行
ModelEngine提供从数据处理、知识生成,到模型微调和部署,以及RAG(Retrieval Augmented Generation)应用开发的AI训推全流程工具链。 GitCode开源地址:https://gitcode.com/ModelEngineGitee开源地址:https…...