为什么枚举,zip,范围类型不属于types.GeneratorType? [英] Why do the enumerate, zip, range types not belong to types.GeneratorType?

查看:190
本文介绍了为什么枚举,zip,范围类型不属于types.GeneratorType?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python 3引入了类似于生成器的对象,该对象将在调用range()zip()时返回.返回的对象就像生成器一样,可以被迭代一次,但是不能很好地打印",就像enumerate() return参数一样.

Python 3 has introduced generator-like objects to be returned upon calling range() and zip(). The object returned acts like a generator and can be iterated through once but doesn't 'print' well, much like the enumerate() return argument.

我很困惑地看到它们是不同的对象类型,不属于types.GeneratorType,或者至少这是types模块显示的内容.一个可以运行的功能期望发电机不会检测到它们.他们的继承是什么?它们是否属于主要的生成器"结构,以便它们例如可以与其他发电机一起被识别?

I was perplexed to see, however, that they are distinct object types and do not belong to types.GeneratorType, or at least this is what the types module shows. A function that would run e.g. expecting a generator would not detect them. What is their inheritance? Do they belong to a main "generator" structure, so that they e.g. could be identified along with other generators?

import types

a = [1,2,3]
b = [4,5,6]

# create some generator-type objects
obj_zip = zip(a,b)
obj_enu = enumerate(a)
obj_r = range(10)

print(type(obj_zip))
print(type(obj_enu))
print(type(obj_r))

# checking against types.GeneratorType returns False
print(isinstance(obj_zip,types.GeneratorType))
print(isinstance(obj_enu,types.GeneratorType))
print(isinstance(obj_r,types.GeneratorType))

# checking against their own distinct object types returns True
print(isinstance(obj_zip,zip))

推荐答案

types.GeneratorType

生成器迭代器对象的类型,由生成器函数创建.

The type of generator-iterator objects, created by generator functions.

生成器功能是该语言中的特定功能;它表示使用yieldyield from的函数(或生成器表达式,它们只是内联生成器函数的简写).它是迭代器集的子集(可以调用next()的所有事物以获取新值),又是迭代器的子集(可以调用iter()的所有事物以获取迭代器;迭代器本身就是可迭代的,其中iter(iterator)充当标识函数.

Generator functions are a specific thing in the language; it means functions that use yield or yield from (or generator expressions, which are just a shorthand for inline generator functions). It's a subset of the set of iterators (all things that you can call next() on to get a new value), which is in turn a subset of iterables (all things that you can call iter() on to get an iterator; iterators themselves are iterables, where iter(iterator) behaves as the identity function).

基本上,如果您要测试我可以对此进行循环吗?",请测试isinstance(obj, collections.abc.Iterable).如果您要检查这是一个穷举的迭代器吗?" (也就是说,我会通过遍历它来耗尽它吗?),测试isinstance(obj, collections.abc.Iterator)或使用基于鸭型的方法,测试iter(obj) is obj(迭代器上的不变式 require 要求iter(iterator)产生原始的迭代器对象不变).

Basically, if you're testing for "can I loop over this?", test isinstance(obj, collections.abc.Iterable). If you're checking "is this an exhaustible iterator?" (that is, will I exhaust it by looping over it?), test either isinstance(obj, collections.abc.Iterator) or for the duck-typing based approach, test iter(obj) is obj (the invariants on iterators require that iter(iterator) yield the original iterator object unchanged).

请注意,range不是 生成器或迭代器.根据文档:

Note that range is not a generator or iterator. Per the docs:

范围实际上不是一个函数,而是一个不变的序列类型,如序列类型-列表,元组,范围.

成为不可变序列类型意味着可迭代的,仅此而已.它通常像是迭代器一样使用,这一事实是无关紧要的.如果它是一个迭代器,那么这里的第二个循环将永远不会执行:

Being an immutable sequence type means it is an iterable, but that's it. The fact that it is usually used as if it were an iterator is irrelevant; if it were an iterator, the second loop here would never execute:

r = range(3)
for i in r:
    print("First", i)
for i in r:
    print("Second", i)

,但效果很好,因为对iter(r)的每个(隐式)调用都会基于相同的底层itera ble返回一个 new itera tor .

but it works just fine, because each (implicit) call to iter(r) returns a new iterator based on the same underlying iterable.

这篇关于为什么枚举,zip,范围类型不属于types.GeneratorType?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆