python - 有没有办法懒惰地解压无限生成器?
问题描述
在这种情况下,我想定义一些整数递增的 ID:
id_a, id_b, id_c = range(3)
这对于少数 ID 来说是可以的。但是如果有很多ID,将来会更多。每次添加新 ID 时都更改 range(n) 数字太繁琐了。因此,我为所有新 ID 创建了一个无限生成器:
def make_id():
c_id = 0
while True:
yield c_id
c_id += 1
或者,直接使用计数:
from itertools import count
make_id = count
然后,我希望我可以像这样定义任意数量的 ID:
id_a, id_b, id_c, id_d, id_e = make_id()
但是,它会导致错误“ValueError:解包的值太多”
顺便说一句,在javascript中没问题:
let make_id = function *() {
let c_id = 0;
while(true) {
yield c_id++;
}
};
const [id_a, id_b, id_c, id_d, id_e] = make_id();
那么,在这种情况下,有没有办法在 python 中懒惰地解压无限生成器呢?
===== 更新 =====
在我的 javascript 项目中,我做了一些事情:
const CFG_DBG = true;
let gen_sym = function *() {
let cur = 0;
while(true) {
if(CFG_DBG) {
yield 'private_attr_' + (cur++).toString();
} else {
yield Symbol();
}
}
};
let [
PRIVATE_ATTR_A, PRIVATE_ATTR_B,
] = gen_sym();
let some_obj = {
"public_attr_a": "this is public a",
[PRIVATE_ATTR_A]: "you shouldn't read this",
};
let some_other_obj = {
[PRIVATE_ATTR_B]: "you shouldn't read this too",
};
它可以确保在发布版本中无法访问的私有属性。
所以,我想在 python 中做这样的事情。我知道“__private_attr”名称,但仍然可以使用前缀访问它。
解决方案
通常,Python 对这类事情要严格得多。您只能使用具有确切大小的可迭代对象来执行此操作。如果迭代是有限的,你可以使用:
a, b, c, *rest = iterable
但这将永远循环无限迭代。当然,它消耗了整个可迭代对象,这不是您想要的。您可以做的一件事是:
from itertools import islice, count
make_id = count()
id_a, id_b, id_c = islice(make_id, 3)
# do some stuff
id_d, id_e = islice(make_id, 2)
但是您仍然必须明确迭代器的大小。
推荐阅读
- ios - iOS 的 MotionLayout
- multithreading - 队列的实现不是线程安全的
- c - 如何强制 gnu ld 使用 -lc 中的符号覆盖我自己的 libc 副本中的符号?
- java - 来自 TextField 的 SimpleIntegerProperty
- javascript - 为脚本添加仅在 Travis CI 中运行而不是在本地运行的权限
- matlab - 无法实例化派生的 MATLAB 类而不会出错
- node.js - Firebase Web Init 错误文件已存在
- javascript - JS - D3 多线时间序列图
- git - 每次提交都会在 git 中创建一个新的树对象吗?
- keras - 在 Keras 中使用 ModelCheckpoint 时的最大递归深度错误