python - 有没有办法懒惰地解压无限生成器?

标签 python generator

在这种情况下,我想定义一些整数递增的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",
};

可以保证release版本不能访问的私有(private)属性。

所以,我想在 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)

但是您仍然必须明确说明迭代器的大小。

关于python - 有没有办法懒惰地解压无限生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62712696/

相关文章:

python - 在 python 中使用 pickle 时内存泄漏

python-2.7 - 我应该如何使用 Google 风格的 Sphinx 记录列表、选项和 yield ?

python - 堆叠式发电机

具有离散颜色图的 Python 2-D 直方图

python - 使用 pip 我安装包当我尝试导入包时它显示一些错误 ImportError no module names "package name"

python - 在 python 未知伪标记中打开 TIFF 时出错

python - 大数据多处理

python - 基于生成器的协程看似无限递归

python - 生成器无法与 Python 中的字节连接

python - 当用 operator.itemgetter 填充时,itertools.groupby 返回空列表项