Python基础教程(三)类和对象、异常处理和模块

8.类与对象

8.1 面向对象

面向对象的三大基本特征: 封装、继承、多态。

在面向对象编程中,封装(Encapsulation)是一种将数据和操作(方法)组合在一起的机制。通过封装,我们可以隐藏数据的具体实现细节,只暴露出一些对外的接口,外部程序只能通过这些接口来访问和操作数据。

封装的主要目的是保护数据的安全性和完整性,防止外部程序直接修改数据,导致不可预料的错误。同时,封装也提供了简化操作的便利性,对外部程序来说,只需要关注公开的接口,而不需要关心具体的实现方式。

在封装中,通常会将数据声明为私有的(private),并提供一些公开的方法(public methods)来获取和修改数据。这些公开的方法可以对数据进行一些校验和处理,保证数据的有效性和一致性。

封装也有助于实现代码的可维护性和可扩展性,通过封装,我们可以将修改数据和操作的逻辑集中在一个地方,方便后续的修改和扩展。

总结来说,封装是一种将数据和操作组合在一起的机制,通过封装可以隐藏数据的实现细节,保护数据的安全性,提供简化操作的接口,并提高代码的可维护性和可扩展性。

继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)从另一个类(称为父类、基类或超类)继承属性和方法。

子类可以继承父类的属性和方法,并且还可以添加自己的特定属性和方法。这样可以实现代码的重用和扩展。

多态是面向对象编程中的一个概念,指的是同一个方法在不同对象上的不同表现形式。简单说,就是通过使用父类的引用指向子类的对象,实现对不同子类对象调用同一个方法时产生不同的结果。

8.2 类与对象

8.2.1 类与对象的关系

类与对象的关系是一种包含与被包含的关系。

类是对一类具有相同属性和行为的对象的抽象描述,它定义了对象的属性和方法。它可以看作是一个模板或蓝图,描述了对象应该具有的特征和行为。

对象是类的实例化,是具体存在的实体,它具有类定义的属性和方法。

类和对象的关系可以用类比现实生活中的一对模具和铸件的关系。类就像是一个模具,定义了对象的特征和行为;对象就像是具体的铸件,是根据模具创建出来的实体。

类与对象的关系还可以用包含与被包含的关系来理解。一个类可以包含多个对象,这些对象都是类的实例化。而一个对象则包含类定义的属性和方法。

总结来说,类是对一类对象的抽象描述,对象是类的实例化,它们之间是一种包含与被包含的关系。

8.2.2 类的定义与访问

class 类名:
        属性名=属性值
        def 方法名(self):
                方法体

>>> class Car:wheels=4def drive(self):print('开车方法')def stop(self):print('停车方法')>>> 

在Python中,self是一个特殊的参数,它代表当前对象实例本身。通过使用self,我们可以在类的方法中引用和操作对象的属性和方法。

在类的方法中,通常第一个参数会被命名为self,用于接收当前对象的引用。当我们调用对象的方法时,Python会自动将对象本身作为第一个参数传递给self。

使用self可以让类的方法操作对象的属性和方法。通过self,我们可以访问和修改对象的属性,调用对象的其他方法,以及在方法中创建临时变量。

实际上,self并不是Python中固有的关键字,我们可以用其他名称来代替self,但约定俗成的做法是使用self。在方法的定义和调用中,都应遵循这个约定,以保持代码的可读性和一致性。

例如,下面是一个简单的示例,演示了如何在类的方法中使用self:

class Person:def __init__(self, name, age):self.name = nameself.age = agedef say_hello(self):print(f"Hello, my name is {self.name} and I am {self.age} years old.")person1 = Person("Alice", 25)
person1.say_hello()  # 输出: Hello, my name is Alice and I am 25 years old.

在上面的例子中,self被用于访问对象的name和age属性。当调用person1对象的say_hello方法时,self会自动接收person1对象的引用,并以此访问和操作对象的属性。

8.2.3 对象的创建与使用

①对象的创建
对象名=类名()
my_car=Car

②访问对象成员
对象名.属性
对象名.方法()

class Car:wheels=4def drive(self):print('开车方法')def stop(self):print('停车方法')my_car=Car()   #创建对象
print(my_car.wheels)#访问对象的成员属性
my_car.drive()     #访问对象的成员方法

8.2.4 访问限制

①定义私有成员
__属性名
__方法名

②私有成员的访问

>>> class PersonInfo:__weight=55def __info(self):print(f'我的体重是:{__weight}')>>> person=PersonInfo()
>>> person.__weight        #类外不访问私有成员,会报错
Traceback (most recent call last):File "<pyshell>", line 1, in <module>
AttributeError: 'PersonInfo' object has no attribute '__weight'
>>> person.__info()
Traceback (most recent call last):File "<pyshell>", line 1, in <module>
AttributeError: 'PersonInfo' object has no attribute '__info'
>>> 

(1) 访问私有属性

可以通过访问公有方法间接访问私有属性

>>> class PersonInfo:__weight=55def get_weight(self):print(f'我的体重是:{self.__weight}kg')>>> person=PersonInfo()
>>> person.get_weight()
我的体重是:55kg

(2) 访问私有方法

可以通过访问公有方法间接访问私有方法

>>> class PersonInfo:__weight=55def __info(self):print(f'体重是:{self.__weight}')def get_weight(self):print(f'我的体重是:{self.__weight}kg')self.__info()>>> person=PersonInfo()
>>> person.get_weight()
我的体重是:55kg
体重是:55
>>>

8.3 构造方法与析构方法

类中有两个特殊的方法: 构造方法 __init__()和析构方法 __del__()

8.3.1 构造方法

>>> class Inforamtion(object):def __init__(self,name,sex):self.name=nameself.sex=sexdef info(self):print(f'姓名:{self.name}')print(f'性别:{self.sex}')>>> infomat=Inforamtion('小王','女')
>>> infomat.info()
姓名:小王
性别:女

8.3.2 析构方法

析构方法(Destructor)是一种特殊类型的方法,用于在对象被销毁之前执行清理操作。在许多编程语言中,每个类都可以定义一个析构方法,该方法没有任何参数,并且在对象被销毁时自动调用。

析构方法通常用于释放对象占用的资源,比如关闭文件、释放内存等。当对象不再被引用或程序结束时,析构方法会被自动调用。在调用析构方法之后,对象的内存空间将被回收。

需要注意的是,有些编程语言不支持析构方法,而是通过垃圾回收机制来自动处理内存释放。在这种情况下,开发人员无需显式定义析构方法,而是让垃圾回收机制自动回收不再使用的对象。

在创建自定义类时,如果需要执行一些清理操作(如关闭连接、释放资源等),可以考虑使用析构方法来实现。一般来说,析构方法应该与构造方法相对应,以确保对象创建和销毁时的一致性和完整性。

import sys
class Destruction:def __init__(self):print('对象被创建')def __del__(self):print('对象被释放')des=Destruction()
print(sys.getrefcount(des))
del(des)

打印出 "des" 实例的引用计数。请注意,由于 sys.getrefcount() 会在使用期间增加一个额外的引用计数,因此打印结果将比预期的引用计数高 1。

8.4 类方法和静态方法

Python中的类除了self修饰的普通方法,还可定义使用@classmethon修饰的类方法和使用@staticmethon修饰的静态方法。

8.4.1 类方法

(1) 类方法使用装饰器@classmethod 修饰。
(2) 类方法的第一个参数为 cls 而非 self,它代表类本身
(3) 类方法即可由对象调用,亦可直接由类调用。
(4) 类方法可以修改类属性,实例方法无法修改类属性。

①定义类方法
类名.类方法
对象名.类方法
②修改类属性

>>> class Test:@classmethoddef use_classmet(cls):print('我是类方法')>>> test=Test()
>>> test.use_classmet()    #类方法即可由对象调用,亦可直接由类调用。
我是类方法
>>> Test.use_classmet()
我是类方法>>> class Apple():count=0def add_one(self):self.count=1@classmethoddef add_two(cls):cls.count=2>>> apple=Apple()
>>> apple.add_one()    #实例方法无法修改类属性,但可以修改实例化对象的属性
>>> print(Apple.count)
0
>>> print(apple.count)
1
>>> apple.add_two()    #类方法可以修改类属性,但不可以修改实例化对象的属性
>>> print(Apple.count)
2

8.4.2 静态方法

(1) 静态方法没有 self 参数,它需要使用@staticmethod 修饰
(2) 静态方法中需要以“类名.方法/属性名”的形式访问类的成员
(3) 静态方法即可由对象调用,亦可直接由类调用。

>>> class Example():num=10@staticmethoddef static_method():print(f'类属性的值为:{Example.num}')print('----静态方法')>>> exp=Example()
>>> exp.static_method()
类属性的值为:10
----静态方法
>>> Example.static_method()
类属性的值为:10
----静态方法

8.5 继承

继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)从另一个类(称为父类、基类或超类)继承属性和方法。

子类可以继承父类的属性和方法,并且还可以添加自己的特定属性和方法。这样可以实现代码的重用和扩展。

下面是一个简单的示例,展示了继承的基本用法:

class Animal:def __init__(self, name):self.name = namedef eat(self):print(f"{self.name} is eating.")class Cat(Animal):def meow(self):print("Meow!")class Dog(Animal):def bark(self):print("Woof!")cat = Cat("Tom")
cat.eat()  # 继承自父类 Animal 的 eat 方法
cat.meow()  # 子类 Cat 自己定义的方法dog = Dog("Max")
dog.eat()  # 继承自父类 Animal 的 eat 方法
dog.bark()  # 子类 Dog 自己定义的方法

在这个例子中,Cat 类和 Dog 类都继承了 Animal 类。它们可以使用父类 Animal 的属性和方法,同时也可以添加自己的方法。

通过继承,子类可以重用父类的代码,同时还可以通过添加新的特定方法来扩展功能。这样可以减少代码的重复编写,提高代码的可维护性和灵活性。

8.5.1 单继承

class 子类(父类):
isinstace()函数和issubclass () 函数

①isinstance()函数是Python内置的一个函数,用来判断一个对象是否属于指定的类型。

isinstance()函数的语法格式如下:

isinstance(object, type)

其中,object是要判断的对象,type是指定的类型。

isinstance()函数的返回值是一个bool类型的值,如果对象是指定类型的实例,返回True;否则,返回False。

下面是一些示例:

x = 5
print(isinstance(x, int))  # 输出True,因为x是int类型的对象y = "hello"
print(isinstance(y, str))  # 输出True,因为y是str类型的对象z = [1, 2, 3]
print(isinstance(z, list))  # 输出True,因为z是list类型的对象a = (1, 2, 3)
print(isinstance(a, tuple))  # 输出True,因为a是tuple类型的对象b = {"name": "Tom", "age": 25}
print(isinstance(b, dict))  # 输出True,因为b是dict类型的对象c = 5.5
print(isinstance(c, float))  # 输出False,因为c不是float类型的对象dog=Dog()
isinstance(dog,Dog)    # 输出True,因为dog是Dog类型的对象

可以看到,isinstance()函数可以用来判断对象的类型,非常方便。

②issubclass()函数是用来判断一个类是否是另一个类的子类的函数。

函数语法:

issubclass(subclass, classinfo)

参数说明:subclass:要判断的类。

      classinfo:要对比的类或元组,可以是一个类对象或由类对象组成的元组

返回值:如果 subclassclassinfo 类的子类或者是 classinfo 类本身,则返回 True,否则返回 False

8.5.2 多继承

多继承指的是一个类可以继承多个父类的特性和行为。在一些编程语言中,如Python,允许一个类同时继承多个父类。

多继承的优点是可以在一个类中获得多个父类的特性和行为,增加了代码的复用性和灵活性。

class 子类(父类A,父类B):

class English:def eng_know(self):print('具备英语知识')
class Math:def math_know(self):print('具备数学知识')class Student(English,Math):def study(self):print('学生的任务是学习')stu=Student()
stu.eng_know()
stu.math_know()
stu.study()执行结果:
>>> %Run main.py
具备英语知识
具备数学知识
学生的任务是学习

8.5.3 方法的重写

class Felines:def feature(self):print('猫科动物特长是爬树')
class Cat(Felines):name='猫'def feature(self):print(f'{self.name}会抓老鼠')print(f'{self.name}会爬树')cat=Cat()
cat.feature()执行结果:
>>> %Run main.py
猫会抓老鼠
猫会爬树

8.5.4 super()函数

super().方法名()

super()函数是一个用于调用父类方法的函数。它返回一个临时对象,这个对象是指向父类的一个实例,通过该对象可以调用父类的方法。在使用super()函数时,通常是在子类的方法内部使用,以便在子类中执行父类的方法,并可以对其进行扩展。通过super()函数,可以实现方法的重写、覆盖或者覆写,从而实现对继承的灵活应用。

class Felines:def feature(self):print('猫科动物特长是爬树')
class Cat(Felines):name='猫'def feature(self):print(f'{self.name}会抓老鼠')print(f'{self.name}会爬树')print('-'*20)super().feature()cat=Cat()
cat.feature()执行结果:
>>> %Run main.py
猫会抓老鼠
猫会爬树
--------------------
猫科动物特长是爬树

8.6 多态

多态的实现方式有两种:继承和接口。继承方式是通过子类继承父类的方法,然后在子类中重写父类的方法,实现多态效果。接口方式是通过定义接口,并让不同的子类实现接口中的方法,然后通过接口引用指向不同实现类的对象,实现多态效果。

多态的好处在于可以提高代码的灵活性和可扩展性。由于多态可以使得同一个方法适用于不同的对象,可以减少重复的代码,提高代码的复用性。另外,通过多态可以实现接口的抽象,可以在不改变接口的情况下扩展程序的功能。

class Animal(object):    #object是所有类的父类def move(self):pass  #pass用来占位保持函数结构的完整,相当于{}
class Rabbit(Animal):def move(self):print('兔子蹦蹦跳跳')class Snail(Animal):def move(self):print('蜗牛缓慢爬行')def test(obj):    #通过参数的不同调用不同的move方法obj.move()rabbit=Rabbit()
test(rabbit)
snail=Snail()
test(snail)#执行结果
'''
>>> %Run main.py
兔子蹦蹦跳跳
蜗牛缓慢爬行
'''

9.异常处理

9.1 除零异常

i=input('请输入数字:')    #当输入为0时,会引发程序无法执行或异常结束
n=12
result=n/int(i)
print(result)
print(f'{n}除以{i}等于{result}')

9.2 捕获异常

在Python中可使用try...except语句捕获一次,try...except还可以与else、finally组合使用实现更强大的异常处理功能。

9.2.1 try...except语句

try:
        可能出错的代码
except [异常类型]:
        错误处理语句

i=input('请输入数字:')
n=12
try:result=n/int(i)print(result)print(f'{n}除以{i}等于{result}')
except:print('除数不能为0!')'''执行结果
>>> %Run main.py
请输入数字:0
除数不能为0!
'''

9.2.2 捕获异常信息

①捕获程序运行时的单个异常
i=input('请输入数字:')
n=12
try:result=n/int(i)print(result)print(f'{n}除以{i}等于{result}')
except ZeroDivisionError as e:    #指定异常类型为除数为零异常print('除数不能为0!')print(f'异常原因:{e}')'''执行结果
>>> %Run main.py
请输入数字:0
除数不能为0!
异常原因:division by zero
'''
②捕获程序运行时的多个异常
try:print(count)demo_list=['Python','java','C','C++']print(demo_list[4])
except (NameError,IndexError) as e:#NameError:未定义名字异常#IndexError:索引越界异常print(f'异常错误原因:{e}')
'''
执行结果
>>> %Run main.py
异常错误原因:name 'count' is not defined
'''try:#print(count)demo_list=['Python','java','C','C++']print(demo_list[4])
except NameError as e:#NameError:未定义名字异常print(f'异常错误原因:{e}')
except IndexError as e:#IndexError:索引越界异常print(f'异常错误原因:{e}')
'''
执行结果
>>> %Run main.py
异常错误原因:list index out of range
'''
③捕获程序运行时的所有异常
try:print(count)demo_list=['Python','java','C','C++']print(demo_list[4])
except Exception as e:          #与"excpt :"一样捕获所有异常print(f'异常错误原因:{e}')
#excpt :
#    print('程序出现异常,原因未知')

9.2.3 else子句

try:
        可能出错的语句
except :
        出错后的执行语句
else:
        未出错时的执行语句

num=input('请输入每页显示多少条数据:')
try:page_num=int(num)
except Exception as e:page_num=10print(f'当前页面显示{page_num}条数据')
else:print(f'当前页面显示{num}条数据')'''
执行结果
>>> %Run main.py
请输入每页显示多少条数据:1
当前页面显示1条数据
>>> %Run main.py
请输入每页显示多少条数据:ts
当前页面显示10条数据
'''

9.2.4 finally子句

try:
        可能出错的语句
except:
        出错后的执行语句
finally:
        无论是否错误都会执行的语句

9.3 抛出异常

9.3.1 raise语句

(1) 由异常类名引发异常
(2) 由异常对象引发异常
(3) 由程序中出现过的异常引发异常

#(1) 由异常类名引发异常
>>>raise NameError
#(2) 由异常对象引发异常
name_error=NameError()
raise name_error
#(3) 由程序中出现过的异常引发异常
try:num
except NameError as e:raise

9.3.2 异常的传递

异常的传递是指在程序中,当一个异常被抛出但没有在当前的代码块中被捕获处理时,它会被传递给调用栈中的上一级代码块进行处理。这样的过程会一直持续,直到异常被捕获或者到达程序的最顶层代码块。

在异常的传递过程中,如果没有捕获到异常,最终会传递到程序的最顶层代码块,如果还没有进行处理,程序将会终止运行,并输出异常信息。因此,在编写程序时,我们应该合理地设计异常处理机制,捕获并处理可能出现的异常,以保证程序的稳定性和可靠性。

def get_width():print('get_width开始执行')num=int(input('请输入除数:'))width_len=10/numprint('get_width执行结束')return width_len
def calc_area():print('calc_area开始执行')width_len=get_width()print('calc_area执行结束')return width_len*width_len
def show_area():try:print('show_area开始执行')area_val=calc_area()print(f'正方形的面积是: {area_val}')print('show_area执行结束')except ZeroDivisionError as e:print(f'捕获到异常: {e}')
if __name__=='__main__':show_area()
'''
执行结果
>>> %Run main.py
show_area开始执行
calc_area开始执行
get_width开始执行
请输入除数:1
get_width执行结束
calc_area执行结束
正方形的面积是: 100.0
show_area执行结束
>>> %Run main.py
show_area开始执行
calc_area开始执行
get_width开始执行
请输入除数:0
捕获到异常: division by zero
'''

9.4 自定义异常

class CustomError(Exception):    #自定义异常类passtry:passraise CustomError('出现错误')    #抛出异常
except CustomError as e:print(e)'''
执行结果
>>> %Run main.py
出现错误
'''

10. 模块

10.1 模块的概念

Python中的模块可分为三类: 内置模块、第三方模块和自定义模块

10.2 模块的导入方式

使用import导入和使用from....import....导入

①使用import导入
import 模块1,模块2,...
模块名.函数名 ()/类名
import 模块名 as 别名

'''
这段代码使用了time模块和random模块,并且还导入了sys模块。
可以使用time.sleep()函数来让程序暂停执行一段时间。
random模块可以用来生成随机数。
sys模块提供了对Python解释器的访问和控制。
'''
import time
import random,systime.sleep(1)    #延时1S

②使用from...import...导入
from 模块名 mport 函数/类/变量
from time import sleep, time
from 模块名 import *
from 模块名 import 函数名 as 别名
from time import sleep as sl
sl(1)        #延时1S

10.3 自定义模块

#main.py
age=13
def introduce():print(f'我的名字是小王,今年{age}岁')#test.py
import main
main.introduce()
print(main.age)'''
执行结果
>>> %Run test.py
我的名字是小王,今年13岁
13
'''#test1.py
from main import introduce
introduce()'''
执行结果
>>> %Run test.py
我的名字是小王,今年13岁
'''

10.4 模块的导入特性

10.4.1 __all__属性

__all__属性是一个列表,用于定义模块中可以被导入的公共接口。当其他模块使用from module import *语句时,只有__all__列表中指定的成员会被导入。如果__all__属性未定义或为空列表,则不允许使用from module import *语句导入任何成员。

#calc.py文件
__all__=['add' , 'subtract']    #只允许导入add,subtractdef add(a, b):return a+b
def subtract(a,b):return a-b
def multiply(a,b):return a*b
def divide(a,b):if b:return a/belse:print('error')#test.py文件
from main import*print(add(2,3))
print(subtract(2,3))
print(multiply(2,3))
print(divide(2,3))'''
执行结果:
>>> %Run test.py
5
-1
Traceback (most recent call last):File "E:\ESP32物联网开发板\4--实验程序\1--MicroPython实验\test.py", line 5, in <module>print(multiply(2,3))
NameError: name 'multiply' is not defined
'''

10.4.2 __name__属性

__name__属性是一个内建属性,用于表示当前模块的名称。

当模块作为主程序运行时,__name__的值为'__main__'。 当模块作为被导入的模块使用时,__name__的值为模块的名称。

这个属性可用于判断在不同的模式下执行不同的代码。例如,可以在模块的主程序中加入以下代码:

if __name__ == "__main__": # 如果模块作为主程序运行,则执行以下代码 main_function()

这样,当模块作为主程序运行时,主函数main_function()会被调用;而当模块被作为被导入的模块使用时,主函数main_function()将不会被调用。

这个属性对于模块的调试和测试非常有用,可以将一些测试代码放在这个判断语句中,只有当模块作为主程序运行时才会执行这些测试代码。

all__=['add','subtract']
def add(a, b):return a+b
def subtract(a,b):return a-b
def multiply(a,b):return a*b
def divide(a,b):if b:return a/belse:print('error')
if __name__=='__main__':print(add(2,3))print(subtract(2,3))print(multiply(2,3))print(divide(2,3))

10.5 Python中的包

10.5.1 包的结构

包的结构一般由多个子包或模块组成,每个子包或模块中包含一组相关的类或功能。这种组织方式的好处是可以更好地管理代码,提高代码的可维护性和可重用性。

包的结构可以按照不同的层次或模块划分,例如按照功能划分、按照模块划分、按照层次划分等。具体的包的结构设计要根据具体的项目需求和开发规范来确定。

10.5.2 包的导入

#module_demo.py文件在package_demo包内
def add(num1,num2):print(num1+num2)#test.py文件
#方法一
from package_demo import module_demo
#package_demo包名,module_demo模块名
module_demo.add(1,3)#方法二
import package_demo.module_demo
package_demo.module_demo.add(1,3)

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

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

相关文章

RuoYi-Vue-Plus (多数据源注解使用、【手动、拦截器】切换数据源)

接上文多数据源配置&#xff1a; RuoYi-Vue-Plus (多数据源配置)-CSDN博客 一、功能演示 代码生成菜单页面&#xff0c; 展示数据源切换 查询主库 查询从库 二、前端传参切换数据源 页面路径&#xff1a; src/views/tool/gen/index.vue 搜索框如下&#xff1a;下面4发送请求时…

技术分享| 前端性能优化——虚拟滚动(Virtual Scroll)

前端遇到大量数据&#xff08;尤其是大数据表&#xff09;的DOM 渲染时&#xff0c;通常会卡顿&#xff0c;需要考虑优化性能问题&#xff0c;这里针对DOM 渲染引出“虚拟滚动”方案&#xff0c; 详细请在以下各文章中详细了解&#xff1a; vue插件 vue-virtual-scroll-list解决…

干货满满,从零到一:编程小白如何在大学成为编程大神?

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

ClickHouse 24.6 版本发布说明

本文字数&#xff1a;14127&#xff1b;估计阅读时间&#xff1a;36 分钟 作者&#xff1a;ClickHouse team 本文在公众号【ClickHouseInc】首发 又到了发布新版本的时间&#xff01; 发布概要 本次ClickHouse 24.6 版本包含了23个新功能&#x1f381;、24项性能优化&#x1f6…

嵌入式人工智能(39-基于树莓派4B的震动传感器和霍尔传感器)

这两个传感器实验比较简单&#xff0c;也都属于力传感器&#xff0c;就放一起做了。 1、震动传感器 震动传感器是一种用于检测和测量物体震动、振动和冲击的设备。它通常由一个敏感元件和一个信号处理单元组成。敏感元件可以是压电材料、光电材料、加速度传感器等。当物体发生…

【Git】git 从入门到实战系列(一)—— Git 的诞生,Linus 如何在 14 天内编写出 Git?

<> 博客简介&#xff1a;Linux、rtos系统&#xff0c;arm、stm32等芯片&#xff0c;嵌入式高级工程师、面试官、架构师&#xff0c;日常技术干货、个人总结、职场经验分享   <> 公众号&#xff1a;嵌入式技术部落   <> 系列专栏&#xff1a;C/C、Linux、rt…

golang JSON序列化

JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 json历史 [外链图片转存失败,源站可能有防盗链机…

看不见的硝烟:中国网络安全三十年沉浮史

2022 年 5 月 16 日&#xff0c;俄罗斯黑客组织 KillNet 向包括美国、英国、德国在内 10 个国家的政府正式 “宣战”。 2022 年 4 月 28 日&#xff0c;一则消息刷屏&#xff0c;北京健康宝在使用高峰期间&#xff0c;遭受到境外网络攻击。北京健康宝保障团队进行了及时有效应…

4G/5G无线视频采集设备如何通过国标28181接入到视频监控接入平台(视频统一接入平台)

目录 一、国标GB/T 28181介绍 1、国标GB/T28181 2、内容和特点 二、4G/5G无线视频采集设备 1、定义 2、主要功能&#xff1a; 3、技术特点 4、应用场景 二、接入准备工作 1、确定网络环境 &#xff08;1&#xff09;公网接入 &#xff08;2&#xff09;专网传输 2、…

一款功能强大的免费开源卸载工具

BCUninstaller&#xff0c;也称为Bulk Crap Uninstaller&#xff08;简称BCU&#xff09;&#xff0c;是一款免费且开源的Windows平台专用程序卸载工具。它的主要功能是帮助用户高效地批量卸载不需要的应用程序和组件&#xff0c;从而优化系统性能。 BCUninstaller功能特点 批…

这本vue3编译原理开源电子书,初中级前端竟然都能看懂

前言 众所周知vue提供了很多黑魔法&#xff0c;比如单文件组件(SFC)、指令、宏函数、css scoped等。这些都是vue提供的开箱即用的功能&#xff0c;大家平时用这些黑魔法的时候有没有疑惑过一些疑问呢。 我们每天写的vue代码一般都是写在*.vue文件中&#xff0c;但是浏览器却只…

【大厂笔试】翻转、平衡、对称二叉树,最大深度、判断两棵树是否相等、另一棵树的子树

检查两棵树是否相同 100. 相同的树 - 力扣&#xff08;LeetCode&#xff09; 思路解透 两个根节点一个为空一个不为空的话&#xff0c;这两棵树就一定不一样了若两个跟节点都为空&#xff0c;则这两棵树一样当两个节点都不为空时&#xff1a; 若两个根节点的值不相同&#xff…

【数据结构】了解哈希表,解决哈希冲突,用Java模拟实现哈希桶

哈希表的概念 哈希表&#xff08;Hash Table&#xff09;是一种高效的数据结构&#xff0c;用于实现快速的数据存储和检索。它通过将数据映射到一个数组的索引位置&#xff0c;从而能够在平均情况下实现O(1)的时间复杂度进行查找、插入和删除操作。 哈希表的基本概念包括以下…

java面向对象重点总结

文章目录 java面向对象重点总结类与实例构造方法方法重载属性与修饰符封装继承多态重构抽象类接口抽象类和接口的区别&#xff1a;集合泛型 java面向对象重点总结 对象是一个自包含的实体&#xff0c;用一组可识别的特性和行为来标识。 面向对象编程&#xff0c;英文叫Object…

flink 1.17 测试

1、配置 2、测试&#xff1a; ./bin/flink run-application -t yarn-application -Dyarn.application.namewordcount -c org.apache.flink.streaming.examples.wordcount.WordCount ./examples/streaming/WordCount.jar --input hdfs://jy/tmp/input --output hdfs://jy/tmp/o…

C++学习:C++是如何运行的

C 是一种强类型的编程语言&#xff0c;支持面向对象、泛型和低级内存操作。它的工作机制包括从编写源代码到生成可执行文件的一系列步骤。C与文件无关&#xff0c;文件只是容纳运行内容的载体&#xff0c;需要对文件以目标系统的规则编译后&#xff0c;才能在目标系统中运行。 …

java算法递归算法练习-数组之和

简单找个题目练习一下递归算法&#xff0c;输入一组数组&#xff0c;使用递归的方法计算数组之和。其实这个题目&#xff0c;用循环的方式也很简单就能解决&#xff0c;直接循环遍历一下相加就行了&#xff0c;但是我们用来练习一下递归。 先来找基线条件和递归条件 基线条件…

springboot+webSocket对接chatgpt

webSocket对接参考 话不多说直接上代码 WebSocket package com.student.config;import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springfram…

matplotLib在图中标出最后一个点的值

import matplotlib.pyplot as plt import numpy as np# 生成100个随机数据 data np.random.rand(100)# 绘制数据 plt.plot(data, labelData Points)# 获取最后一个数据点的位置和值 last_x len(data) - 1 last_y data[-1]# 用红圈标出最后一个点 plt.plot(last_x, last_y, r…

STM32-寄存器DMA配置指南

配置步骤 在STM32F0xx中文参考手册中的DMA部分在开头给出了配置步骤 每个通道都可以在外设寄存器固定地址和存储器地址之间执行 DMA 传输。DMA 传输的数据 量是可编程的&#xff0c;最大达到 65535。每次传输之后相应的计数寄存器都做一次递减操作&#xff0c;直到 计数为&am…