5.5 Python 迭代器与生成器

news2024/11/8 21:47:14

文章目录

      • 1. 三元表达式
        • 1.1 格式
        • 1.2 示例
        • 1.3 嵌套
      • 2. 生成式
        • 2.1 列表生成式
        • 2.2 字典生成式
        • 2.3 集合生成式
        • 2.4 元组生成式
      • 3. 可迭代对象
      • 4. 迭代器
        • 4.1 迭代器的优缺点
        • 4.2 迭代器的惰性机制
        • 4.3 生成迭代器
        • 4.4 文本IO包装器
        • 4.5 字符串迭代器
        • 4.6 列表迭代器
        • 4.7 字典键迭代器
        • 4.8 元组迭代器
        • 4.9 集合迭代器
        • 4.10 注意事项
        • 4.11 模拟for循环
          • 1. 执行步骤
          • 2. 异常捕获
          • 3. while循环遍历迭代器对象
          • 4. 递归遍历迭代器对象
      • 5. 生成器
        • 5.1 生成器生成式
        • 5.2 生成器的特点
        • 5.3 yield关键字
          • 1. 返回生成器
          • 2. 迭代取值
          • 3. yield传参
        • 5.4 实例
      • 6. 练习

1. 三元表达式

1.1 格式
当需求为二选一的情况下推荐使用三元表达式.
格式: 条件成立采用的值 if 条件 else 条件不成立采用的值.
值不能是关键字, ... 属于特殊的符号, 不是关键字.
1.2 示例
a = 0
b = 1
print(a if a > b else b)

def func1():
    print('哈哈哈')
    
while True:
    # 当输入不'q时' 执行func1, 否则什么都不做
    func1() if input('输入q退出否则继续>>>:').strip() == 'q' else ...
1.3 嵌套
三元表达式可以嵌套使用, 尽量不要去使用, Python语句注重可读性, 嵌套太复杂了.
a = 0
b = 1
c = 2
# 从左往右开始执行
print(a if a > b else (c if c > b else a))

2. 生成式

生成式(comprehensions), 也称推导式, 作用是为容器类型快速生成元素.
生成式中for与if一起使用, 则不能搭配else, 应为else从句能跟for也能跟if这会会出现矛盾.
2.1 列表生成式
列表生成式语法: [满足条件执行的表达式 for 迭代变量 in 容器对象]
# 先执行for遍历将容器中的值赋给i, 在列表其它位置就可以使用i, 这里i仅作为列表的元素.
print([i for i in range(10)])  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list1 = ['kid', 'qz', 'qq']
# 先执行for遍历将容器中的值赋给i, i在做字符串拼接.
print([i + '_vip' for i in list1])  # ['kid_vip', 'qz_vip', 'qq_vip']

list1 = ['kid_vip', 'qz_vip', 'qq_vip']
# 先执行for遍历将容器中的值赋给i, i做移除字符串操作.
print([i.strip('_vip') for i in list1])  # ['kid', 'qz', 'qq']

# 复杂格式, 先执行for, 在执行if语句, 
list1 = ['kid_vip', 'qz_vip', 'qq_vip']
# 遍历列表, 取出元素马上进行if判断
print([i.strip('_vip') for i in list1 if i == 'kid_vip'])  # ['kid']

# 面试题
list1 = [lambda x: x + i for i in range(10)]
# 保存十个匿名函数
print(list1)
# [<function <listcomp>.<lambda> at 0x000001D0B252F700>, ...]
# 调用第一个匿名函数
print(list1[0](10))  # 19
# 调用第二个匿名函数
print(list1[1](10))  # 19
# 调用第三个匿名函数
print(list1[2](10))  # 19

函数具有调用时才查找变量的特性, 在没调用之前它不会保存变量的具体值.
只有调用它的时候, 才逐一去找这些变量的具体值, 无所调用第几个匿名函数, 变量i已经循环完毕, 变成9.
# i=i 将i的值保存下来
list1 = [lambda x, i=i: x + i for i in range(10)]
print(list1[0](10))  # 10
print(list1[1](10))  # 11

2.2 字典生成式
# 字典创建方式
list1 = ['name', 'age', 'hobby']
list2 = ['kid', 18, 'red']

dic = {}
for i in range(len(list1)):
    dic[list1[i]] = list2[i]

print(dic)  # {'name': 'kid', 'age': 18, 'hobby': 'red'}
# 字典生成式
list1 = ['name', 'age', 'hobby']
list2 = ['kid', 18, 'red']


res = {list1[i]: list2[i] for i in range(len(list1))}  

print(res)  # {'name': 'kid', 'age': 18, 'hobby': 'red'}
2.3 集合生成式
list1 = ['name', 'age', 'hobby']

res = { i for i in list1}  
print(res) # {'hobby', 'age', 'name'}

2.4 元组生成式
()被python中的生成器占用, 想要使用元组生成式在括号前面加上关键字tuple.
print(tuple(x for x in range(5)))  # (0, 1, 2, 3, 4)

3. 可迭代对象

迭代: 迭代即更新的意思, 每次更新都必须依赖上一次的结果, 其目是为了更逼近所需结果.
可迭代对象: 即可以进行迭代操作的一类对象, 能被for循环遍历取值的对象的都是可迭代对象.
内置isinstance(Object, Iterable)函数: 判断一个对象是否是可迭代对象.

管方解释说只能识别对象含有.__iter__()方法的对象,
那么意味着对象含有.__iter__()方法都是'可迭代对象'.

一般情况下所有的双下方法都会有一个与之对应的简化写法的函数.
: .__iter__()方法 --> iter()函数.
针对双下划线开头, 双下滑线结尾的方法标准的读法是'双下方法名', : 双下iter.
# 导入Iterable类
from collections import Iterable

str1 = ''
print(isinstance(str1, Iterable))  # True

str1.__iter__()


4. 迭代器

迭代器: 是一种通过迭代方式取值的方式, 从序列的第⼀个元素开始访问, 直到所有的元素被访问完, 结束.
迭代器可以记住遍历对象所在的位置, 只能往后取值, 不会后退. 
通常含有.__next__()方法的对象就是迭代器.
4.1 迭代器的优缺点
迭代器的优点: 节省内存, 迭代器在内存中只占一个数据的空间.
每次通过next()取值, 便会计算出一个值, 内存空间内加载当前的值, 将上一条值舍弃.

迭代器的缺点: 不能直观的查看里面的数据, 取值时不走回头路, 只能一直向下取值.
取值方式对比:
迭代取值: 是通用取值方式, 不依赖于索引取值. 特点: 永远都是往下一个取值, 无法重复获取.
索引取值: 不通用取值方式, 有序的容器类型, 才能使用. 特点: 可以重复取值.
4.2 迭代器的惰性机制
迭代器的惰性机制: next一次, 取一个值, 绝不过多取值.
迭代是数据处理的基石, 内存中放不下的数据集时,
需要一种惰性获取数据项的方式, 即按需一次获取一个数据项, 这就是迭代器模式.
4.3 生成迭代器
字符串, 列表, 字典, 元组, 集合, 文件都是可迭代对象, 通过.__iter__()方法实例化得到迭代器.
迭代取值固定语法: for element in Iterable, for语句内部通过.__next__()方法获取迭代器对象的元素.
直接使用.__next__()方法取值, 一次取出一个, 取完再取则报错:
: StopIteration.
: 停止迭代.
4.4 文本IO包装器
文件对象本身就是迭代器对象.
"""
a.txt内容:
1
2
3
"""

# 获取文件句柄
rf = open('a.txt', 'rt')
text_io_wrapper = rf.__iter__()

print(text_io_wrapper, type(text_io_wrapper))
# <_io.TextIOWrapper name='a.txt' mode='rt' encoding='cp936'> <class '_io.TextIOWrapper'>
print(text_io_wrapper.__next__())  # 1 和换行符号 \n

# 文件对象本身就是迭代器对象.
print(rf, type(rf))
# <_io.TextIOWrapper name='a.txt' mode='rt' encoding='cp936'> <class '_io.TextIOWrapper'>
print(rf.__next__())  # 2 和换行符号 \n

4.5 字符串迭代器
# 字符串迭代器
str_iterator = '123'.__iter__()
print(str_iterator, type(str_iterator))
# <str_iterator object at 0x0000029C1387E220> <class 'str_iterator'>

# 迭代取值
print(str_iterator.__next__())  # 1
print(str_iterator.__next__())  # 2
print(str_iterator.__next__())  # 3
print(str_iterator.__next__())  # 报错: StopIteration

4.6 列表迭代器
# 列表迭代器
list_iterator = [1, 2, 3].__iter__()
print(list_iterator, type(list_iterator))
# <list_iterator object at 0x0000017B2A84E220> <class 'list_iterator'>

print(list_iterator.__next__())  # 1
print(list_iterator.__next__())  # 2
print(list_iterator.__next__())  # 3

4.7 字典键迭代器
# 字典键迭代器
dict_keyiterator = {'k1': 'v1', 'k2': 'v2'}.__iter__()
print(dict_keyiterator, type(dict_keyiterator))
# <dict_keyiterator object at 0x000001CBE3AD2310> <class 'dict_keyiterator'>


print(dict_keyiterator.__next__())  # k1
print(dict_keyiterator.__next__())  # k2

4.8 元组迭代器
# 元组迭代器
tuple_iterator = (1, 2, 3).__iter__()
print(tuple_iterator, type(tuple_iterator))
# <tuple_iterator object at 0x0000026FDA31E220> <class 'tuple_iterator'>

print(tuple_iterator.__next__())  # 1
print(tuple_iterator.__next__())  # 2
print(tuple_iterator.__next__())  # 3

4.9 集合迭代器
# 集合迭代器
set_iterator = {1, 2, 3}.__iter__()
print(set_iterator, type(set_iterator))
# <set_iterator object at 0x000001F6F1D567C0> <class 'set_iterator'>

print(set_iterator.__next__())  # 1
print(set_iterator.__next__())  # 2
print(set_iterator.__next__())  # 3

4.10 注意事项
每次执行.__iter__()方法都生成一个新的迭代器对象, 都是第一次迭代取到的值是同一个值.
str1 = 'abc'

print(str1.__iter__().__next__())  # a
print(str1.__iter__().__next__())  # a
print(str1.__iter__().__next__())  # a
print(str1.__iter__().__next__())  # a

4.11 模拟for循环
1. 执行步骤
for循环执行步骤:
* 1. in关键字后面的序列类型调用.__iter__()方法转为迭代器对象.
* 2. 循环执行.__next__()方法取值.
* 3. 取完之后再次执行.__next__()就会报错, 会自动捕获错误并处理.
2. 异常捕获
异常: 是一个事件, 该事件会在程序执行过程中发生, 影响程序的正常执行.
在解释器无法正常处理程序时就会发生异常, 程序会终止执行.

错误类型: 
* 1. 语法错误: 解释器在解释源文件语句前会进行语法检测出的错误, 源代码不符合Python的编写规范.
* 2. 逻辑错误: 程序执行之后出现的错误, 语法正确, 但其代码违反逻辑规则而产生的错误, 种类很多...
异常信息三个组成部分:
* 1. 回溯信息: 最近一次错误所在行:
Traceback (most recent call last):
  File "xxx", line 1, in <module>
    ...
* 2. 错误类型: 
NameError: xxx...
* 3. 冒号后面的错误的详情原因, 解决bug的关键.

语法错误必须立刻修改, 否则程序无法执行. 出现逻辑错误可以进行针对性处理, 觉得是都让程序继续运行.
异常处理语法格式:
try:
	被检测的代码.
except 错误类型 as 接收错误信息的变量:
	被检测代码出错后的处理机制.
try:
    name
except NameError as e:
    print(e, '结束程序运行!')  # name 'name' is not defined
    
Exception 是所有异常的父类, 所有异常都可以检测到.
3. while循环遍历迭代器对象
# while方法模拟for循环
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55]
# 生成迭代器对象
list_iterator = l1.__iter__()

count = len(l1)
while count:
    i = list_iterator.__next__()
    print(i)
    count -= 1
    
# 异常捕获停止跌倒
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55]
list1 = l1.__iter__()
while True:
    try:
        print(list1.__next__())
    except Exception:
        break
        
* try语句检测程序会占用额外的资源, 执行一次就有一句try语句, 不推荐使用大量的try语句.
4. 递归遍历迭代器对象
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55]
# 生成迭代器对象
list_iterator = l1.__iter__()

count = len(l1)


def func(counts):
    if counts == 0:
        return
    i = list_iterator.__next__()
    print(i)
    return func(counts - 1)


func(count)

l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55]
# 生成迭代器对象
list1 = l1.__iter__()


def func(list1):
    try:
        print(list1.__next__())
    except Exception:
        return
    return func(list1)


func(list1)

5. 生成器

有时候序列或集合的元素的非常多, 如果所有对象都直接存放在内存中, 会占用大量内存的资源.
于是设计出一种按某种顺序推导元素的算法, 需要哪个元素就迭代计算出哪个元素, 而不必创建完整的元素集合.
每次仅占用一个元素的空间, 元素被取出后, 给下一个计算结果使用, 从而节省大量的空间.
在Python中这种计算出元素的机制, 称为生成器: generator. 

生成器属于自定义迭代器, 生成器保存的是计算元素的算法或表达式, 可以使用for迭代取值.
5.1 生成器生成式
Python规定生成器生成式使用()圆括号.
生成器生成式能够快速生成一个生成器, 保存了计算元素的算法.
只有在迭代取值的时候才会执行计算元素的算法, 每次仅提供一个元素.
g1 = (i for i in range(10))
print(g1)  # generator 生成器

print(next(g1))  # 0
print(next(g1))  # 1
print(next(g1))  # 2


# 迭代取值计算出元素
for i in g1:
    print(i, end=' ')  # 3 4 5 6 7 8 9

5.2 生成器的特点
生成器的特点, 在使用的时候才会计算, 通过一个案例来讲解:
# a.txt
123456789
123456789
123456789
with open('a.txt') as f:
    # 生成器生成式
    g1 =(len(line) for line in f)  # 这一步其实没有读取文件, 简单来说就是将表达式保存什么都没干.

print(sum(g1))  # 这一步才执行生成器, 去读取文件, 但是文件句柄已经回收了

为何报错?ValueError: I/O operation on closed file.
ValueError: 对已关闭文件的 IO 操作.

迭代器只有在使用的时候才执行, 元组生成式走了过场什么都什么做.

你以为代码是: (换行'\n'算一个字符.)
g1 = (10, 10, 9) 
其实代码是这样的:
g1 = (len(for line in f), len(for line in f), len(for line in f)
当需要执行的时候, 文件的io操作已经关闭了, 所有报错.
with open('a.txt') as f:
    g1 = (len(line) for line in f)  
    
    # 在没有回收文件句柄的时候代码就可以正常的执行.
    print(sum(g1))  # 29
    
5.3 yield关键字
yield关键字: 在函数内使用, 调用函数时, 函数不会执行, 而是返回一个生成器.

yield的作用:
* 1. 当函数体内含有yield关键字时, 那么在调用函数的时候, 函数体代码不会执行, 而是返回一个生成器.
* 2. 可以使用yield设置返回值, 也就是生成器的元素, 多个值会组织成元组, 不写默认返回None.
* 3. 第三种传值的方式, yeied可以传递参数.

1. 返回生成器
当函数体内含有yield关键字时, 那么在调用函数的时候, 函数体代码不会执行, 而是直接返回一个生成器.
# 函数中有yield语句
def func():
    print('你好')
    yield

    
# 函数内体代码执行了, 它的状态没有被展示出来.
res = func()  
# 返回生成器对象
print(res, type(res))  # <generator object func at 0x000001B84AE463C0> <class 'generator'>

2. 迭代取值
调用.__next__()方法取值时才会执行函数中的语句, 遇到yield语句返回一个值, 并保存当前函数的执行状态.
下一个次.__next__()方法则从上次暂停的位置处往回执行, 后续没有yield则执行到底.
def func():
    num = 0
    print(num)
    # 通过yield返回值
    yield 'yield1'

    num += 1
    print(num)
    # 通过yield返回值
    yield 'yield2'

    num += 1
    print(num)


# 接收生成器
res = func()
# 迭代取值, 遇到yield语句则返回跟随它的值, 并且会暂停函数的运行保存函数的状态.
print(res.__next__())
# 再次迭代取值, 让函数继续运行, 从上次暂停的位置开始往后执行.
print(res.__next__())
# 函数还没执行完, 还需要通过.__next__()方法让程序继续完后执行,
# 但执行之后.__next__()方法要求必须有返回值(也是就说说必须要有yield语句),
# 后续并没有yield语句则会报错: StopIteration.
try:
    res.__next__()
# 报错没有提示信息, 空白.
except StopIteration as e:
    print(e)

运行工具窗口显示:
0
yield1
1
yield2
2

GIF 2022-12-15 23-44-51

# yield返回值
def func():
    num = 0
    print(num)
    # 通过yield返回值
    yield 'yield1'

    num += 1
    print(num)
    # 通过yield返回值
    yield 'yield2'

    num += 1
    print(num)


# 接收生成器
res = func()
# for迭代取值
for i in res:
    print(i)

# yield默认返回值
def func():

    print(1)
    # 默认返回None
    yield


# 接收生成器
res = func()
# 迭代取值
for i in res:
    print(i)  # None
    
3. yield传参
yield传参格式:
生成器函数.send(参数1, ···), .send()方法可以让函数运行(包括yield停止的情况), 遇到yield停止.
函数中接收参数:
value=yield  
程序中第一次使用生成器调用.send()方法时, 不能使用带参数的send()函数.
def my_ge():

    num = yield
    print(num)  # None


res = my_ge()
# 使用.send方法让函数运行
print(res.send(None))

# 第一次调用传递给None的参数
def my_ge():

    num = yield
    print(num)


res = my_ge()
print(res.send(1))  # 报错

运行工具窗口显示:
Traceback (most recent call last):
  File "C:\Users\13600\PycharmProjects\test\test.py", line 8, in <module>
    print(res.send(1))
TypeError: can't send non-None value to a just-started generator

: TypeError: can't send non-None value to a just-started generator.
: 无法向刚启动的生成器发送非None值,
yield语句的完整执行顺序: 
* 0. 调用含有yield的函数, 函数体代码不会执行, 而是返回一个生成器, 这里可以称为生成器函数.
* 1. 使用.__next__()方法时会执行函数体代码
* 2. 遇到yield语句则返回跟随它的值(双下next方法就是要这个值), 并且会暂停函数的运行保存函数的状态.
* 3. 生成器函数通过.send方法()返回一个参数给yield语句执行的结果.
* 4. 使用变量接收yield语句执行的结果.
* 5. 后续可以使用send传递的参数.

执行过yield语句后, 才能使用.send()方法传值给yield, 
这个值作可以理解为yield语句执行的结果, 可以使用变量接收.
def my_ge():
    while True:
        print('执行my_ge函数!')
        # num接收 yield语句执行的结果
        num = yield '可以传递了!'
        # 使用num
        print(num)


res = my_ge()

print(res.__next__())  # 遇到yield停止, 打印yield返回的结果
res.send(1)  # 传递参数给 yield
res.send(2)  # 传递参数给 yield

GIF 2022-12-16 0-39-40

5.4 实例
def func1():
    for i in range(10):
        yield i + 1 - 1 * 2 / 2


def func2():
    res = func1()

    for i in res:
        print(i)


func2()

# 模仿range函数
def my_range(start_num, end_num=None, len_num=1):
    # 没有提供终止位参数, 则将起始为参数作为终止位参数, 将起始位设置为0.
    if not end_num:
        end_num = start_num
        start_num = 0
	
    # while循环, 设置循环停止添加, 当起始位的值等于终止位的值时停止循环.
    while start_num < end_num:
        # 返回参数
        yield start_num
        # 参数自增, 默认为1
        start_num += len_num


for i in my_range(1, 10, 2):
    print(i)
    
# 面试题
def test():
    for i in range(4):
        yield i


# 得到一个生成器
g = test()


for n in [1, 10]:
    # 再次得到一个生成器, 生成器中的for不会执行, 它不会保存值只保留表达式.
    g = (i + n for i in g)
"""
n = 1 
g = (i + n for i in g)
n = 10
g = (i + n for i in (i + n for i in test()))
"""

res = list(g)
"""
g = (i + n for i in (i + n for i in (0, 1, 2, 3))  # n 为 10.
g = (i + 10 for i in (i + 10 for in (0, 1, 2, 3))  
g = (i + 10 for i in (10, 11, 12, 13)
g = (10+10, 11+10, 12+10, 13+10
"""
print(res)  # 20 21 22 23

6. 练习

1. 使用递归打印斐波那契数列(前两个数的和得到第三个数, : 1, 2, 3, 5, 8, 13..)
def num(x, y):
    if y > 100:  # 结束条件
        return

    # z = y
    # y = x + y
    # x = z
    
    y, x = y + x, y
    print(y, end=' ')  # 1 2 3 5 8 13 21 34 55 89 144 
    
    num(x, y)
    
num(0, 1)
2. 一个嵌套很多层的列表, 用递归取出所有的值.
list1 = [1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15]]]]]]]


def get_num(list1):
    if not len(list1):  # 结束条件
        return

    for i in list1:
        # i是整数就打印
        if type(i) == int:
            print(i, end=' ')
        # 否则就 递归
        else:
            get_num(i)


get_num(list1)

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

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

相关文章

怎么改图片尺寸更方便?在线图片改大小的使用方法

图片怎么快速改尺寸呢&#xff1f;在网上传图或者做其他用途时&#xff0c;经常会对图片的尺寸有要求&#xff0c;当拍摄或者制作的图片太大或者太小时&#xff0c;都会导致图片的无法正常使用&#xff0c;那么就需要按照规定将图片改大小之后才能正常使用。 在遇到图片修改大…

ui自动化中,隐式等待和显示等待什么时候使用

隐式等待 在页面刷新加载时&#xff0c;页面元素还没有出来&#xff0c;这个时候如果去找元素就会找不到报错 或者点了一个菜单&#xff0c;页面加载时 用笨办法&#xff0c;就是用sleep等待固定的时间&#xff0c;这种浪费的时间比较多&#xff0c;就可以用隐式等待&#xf…

酷暑骄阳,热情似火丨deepin校园联盟走进湖北大学,共话开源新篇章

内容来源&#xff1a;deepin&#xff08;深度&#xff09;社区 炎炎夏日&#xff0c;骄阳似火&#xff0c;6月11日&#xff0c;deepin校园联盟湖北大学站交流活动如期举行。在湖北大学计算机与信息工程学院&#xff0c;deepin(深度)社区研发工程师王溢学为热情似火的学子们开展…

打造地下管廊智慧监测解决方案-守护城市生命线|计讯物联

方案背景 地下综合管廊是城市基础设施的关键部分&#xff0c;即在城市地下建造一个隧道空间&#xff0c;将电力、通信&#xff0c;燃气、供热、排水等各种工程管线集于一体&#xff0c;被视为城市的“生命线”。随着城市化进程的加快&#xff0c;地下管线的数量、种类和密度不断…

动态规划:最长重复子数组

本题不算难&#xff0c;但是如果直接想dp数组怎么定义的话就会头晕&#xff0c;先想递推公式的含义就知道为什么需要冗余的dp[0][0]了 class Solution {public int findLength(int[] nums1, int[] nums2) {int res 0;//1.确定dp数组含义int[][] dp new int[nums1.length1][nu…

不懂产品和工艺的小白能学好FMEA吗?

在制造业的广阔天地里&#xff0c;FMEA&#xff08;Failure Modes and Effects Analysis&#xff0c;失效模式与影响分析&#xff09;一直被视为质量控制的关键武器。然而&#xff0c;很多人认为只有懂产品和工艺的行家才能玩转FMEA&#xff0c;对于小白来说似乎遥不可及。今天…

智慧环保一体化平台简介

据悉&#xff0c;环保问题日益受到人们的关注&#xff0c;智慧环保一体化平台作为解决环保问题的有力工具&#xff0c;正逐渐走进人们的视野。朗观视觉智慧环保一体化平台通过整合各类环保资源&#xff0c;实现环境数据的实时监测、分析与管理&#xff0c;为环境保护提供智能化…

windows10蓝屏原因自检记录

背景 跑训练的过程中电脑自动重启了&#xff0c;为了满足长期训练的需要&#xff0c;研究一下死机原因 查看系统日志 右键我的电脑——管理——系统工具——事件查看器——系统 检索级别为错误的内容&#xff0c;在死机时间附近查找相关日志&#xff0c;发现如下日志 计算机…

【第六篇】SpringSecurity的权限管理

一、权限管理的实现 服务端的各种资源要被SpringSecurity的权限管理控制可以通过注解和标签两种方式来处理。 放开了相关的注解后在Controller中就可以使用相关的注解来控制了 JSR250注解 /*** JSR250*/ @Controller @RequestMapping("/user") public class UserC…

深度!千字长文拆解AI Agent ,浅谈国内AI Agent 现状

“现如今ChatGPT的热度逐渐褪去&#xff0c;而字节的扣子逐渐被越来越多的国人知晓&#xff0c;钉钉、百度、Dify等也纷纷涉足工作流功能&#xff0c;打开国内AI工作流to B市场。今天学姐将用通俗易懂的方式讲解AI Agent是什么&#xff0c;以及国内大厂做Agent的进展。大家不要…

机器人中roll/pitch/yaw angles 和Euler angles的区别

在机器人学和航空领域&#xff0c;roll、pitch、yaw angles&#xff08;滚转角、俯仰角、偏航角&#xff09;和Euler angles&#xff08;欧拉角&#xff09;是两个经常出现的概念&#xff0c;它们用于描述物体在三维空间中的姿态或方向。以下是对这两个概念的解释以及它们之间的…

DeepSpeed Monitoring Comm. Logging

Monitoring 支持多种后端&#xff1a;Tensorboard、WandB、Comet、CSV文件&#xff1b; TensorBoard例子&#xff1a; 自动监控&#xff1a;DeepSpeed自动把重要metric记录下来。只需在配置文件里enable相应的看板后端即可&#xff1a; {"tensorboard": {"enabl…

园区数字化运营管理平台的优势、价值有哪些?

​随着全球及我国数字经济的蓬勃发展&#xff0c;数字化转型已成为各行各业提升效率和竞争力的关键。园区作为区域经济发展的重要载体&#xff0c;数字化运营管理平台更是成为了推动园区经济高质量发展的重要工具。 随着园区数字化运营管理平台的而引入&#xff0c;为园区在运…

FISCO BCOS x GitLink,为国产开源技术生态注入新活力

作为中国领先的区块链底层平台之一&#xff0c;FISCO BCOS 自成立以来始终致力于推动国产开源区块链技术的应用和普及。近期&#xff0c;FISCO BCOS 将开源代码托管到CCF官方代码托管平台 GitLink &#xff08;确实开源&#xff09;&#xff0c;为国产开源技术生态注入新活力。…

github 本地仓库上传及报错处理

一.本地文件上传 这里为上传部分&#xff0c;关于gitbash安装配置&#xff0c;读者可自行搜索&#xff0c;由于已经安装完成&#xff0c;未进行截图保存&#xff0c;这里便不做赘述。 1.登录git账号并创建一个仓库 点击仓库打开后会看到这个仓库的网址链接&#xff08;这个链…

SAP 价格金额信息控制

1)migo / mb51/mb51/mb59 关于价格和金额的显示&#xff0c;需要权限控制&#xff0c;当权限对象F_BKPF_BUK,检查对应【公司代码】 和 ACTVT有03’的权限&#xff0c;如果没有03的权限&#xff0c;对应行的价格和金额显示为空 关于价格和金额的显示&#xff0c;需要权限控制&a…

java:【@ComponentScan】和【@SpringBootApplication】扫包范围的冲突

# 代码结构如下&#xff1a; 注意【com.chz.myBean.branch】和【com.chz.myBean.main】这两个包是没有生重叠的。 主程序【MyBeanTest1、MyBeanTest2、MyBeanTest3】这两个类是在包【com.chz.myBean.main】下 # 示例代码 【pom.xml】 org.springframework.boot spring-boot-…

vue页面和 iframe多页面无刷新方案和并行存在解决方案

面临问题 : back的后台以jsp嵌套iframe为主, 所以在前端框架要把iframe无刷新嵌套和vue页面进行并行使用,vue的keep-alive只能对虚拟dom树 vtree 进行缓存无法缓存iframe,所以要对iframe进行处理 tab标签的切换效果具体参考若依框架的tab切换,可以去若依看源码,若依源码没有实…

Prometheus——部署详解

目录 一、Prometheus Server端安装和相关配置 1.上传安装包并解压 2.配置系统启动文件 3.启动 二、部署Node Exporters监控系统指标 三、监控Mysql配置示例 1.Mysql服务器操作 2.Prometheus服务器操作 四、监控Nginx配置示例 1.在Nginx服务器操作 2.Prometheus服务器…

裂变客户秘籍:PLG SaaS企业如何把握未来增长机遇

在数字化浪潮下&#xff0c;SaaS&#xff08;软件即服务&#xff09;行业正以前所未有的速度发展。产品驱动增长&#xff08;PLG&#xff09;作为SaaS行业的一大趋势&#xff0c;已经成为众多企业获取用户、提升市场份额的重要策略。然而&#xff0c;面对日益激烈的市场竞争和不…