检测对象是否可重复迭代

2024-02-23

Does obj == iter(obj)暗示obj不是可重复迭代的,反之亦然?我在文档中没有看到任何这样的措辞,但根据这条评论 https://stackoverflow.com/questions/9884132/what-exactly-are-pythons-iterator-iterable-and-iteration-protocols#comment62722931_9884259,标准库检查一个对象是否是可重复迭代 通过测试if iter(obj) is obj https://hg.python.org/cpython/file/ce31ee3b1e69/Lib/statistics.py#l551:

@agf:Python 标准库的某些部分依赖于规范的这一部分;他们通过测试来检测某物是否是迭代器/生成器if iter(obj) is obj: https://hg.python.org/cpython/file/ce31ee3b1e69/Lib/statistics.py#l551,因为真正的迭代器/生成器对象将具有__iter__定义为恒等函数。如果测试为真,它们将转换为list允许重复迭代,否则,假设该对象是可重复迭代的,并且可以按原样使用它。
暗影游侠 https://stackoverflow.com/users/364696/shadowranger 6 月 3 日 17:23 https://stackoverflow.com/questions/9884132/what-exactly-are-pythons-iterator-iterable-and-iteration-protocols#comment62722931_9884259

该文档确实指出,如果obj是一个迭代器,要求iter(obj)回报obj。但我认为这不足以得出结论,可以使用以下方法来识别不可重复迭代的对象iter(obj) is obj.


所有迭代器都是可迭代对象,但并非所有可迭代对象都是迭代器。

唯一的要求 https://docs.python.org/3/library/stdtypes.html#container.__iter__可迭代的一个特点是它定义了一个__iter__()返回迭代器的方法:

需要为容器对象定义一种方法来提供迭代支持:

container.__iter__()
返回一个迭代器对象。

An iterator https://docs.python.org/3/library/stdtypes.html#iterator-types必须遵循迭代器协议,它有两个要求:

  1. 它有一个__iter__() method 返回对象本身 https://docs.python.org/3/library/stdtypes.html#iterator.__iter__:

    iterator.__iter__()
    返回迭代器对象本身。

  2. 它有一个__next__()方法,每次调用时返回下一个项目,并且一旦耗尽,就会引发StopIteration 在随后的每次通话中 https://docs.python.org/3/library/stdtypes.html#iterator.__next__:

    一旦迭代器的__next__()方法引发StopIteration,它必须在后续调用中继续这样做。不遵守此属性的实现将被视为已损坏。

这些要求意味着迭代器永远不可重复,并且您始终可以通过确认以下内容来确认可迭代器是迭代器(因此根据定义不可重复)iter(obj) is obj is True:

def is_unrepeatable(obj):
    return iter(obj) is obj

However:因为可迭代的唯一要求是iter(obj)回报some迭代器,你can't证明它is可重复。一个可迭代对象可以定义一个__iter__()每次调用时返回具有不同行为的迭代器的方法:例如,它可以返回一个在第一次调用时迭代其元素的迭代器,但在后续调用中,返回一个立即引发的迭代器StopIteration.

这种行为会很奇怪(而且很烦人),但并不被禁止。这是一个不是迭代器的不可重复可迭代类的示例:

class Unrepeatable:

    def __init__(self, iterable):
        self.iterable = iterable
        self.exhausted = False

    def __iter__(self):
        if self.exhausted:
            return
        else:
            self.exhausted = True
            yield from self.iterable
>>> x = Unrepeatable([1,2,3])
>>> list(x)
[1, 2, 3]
>>> list(x)
[]
>>> iter(x) is x
False
>>> 

我会毫不犹豫地称这种“假迭代器”行为不良,而且我无法想象你会在野外找到一个迭代器的情况,但正如上面所演示的,这是可能的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测对象是否可重复迭代 的相关文章

随机推荐

  • 使用 PHP unlink() 方法后获取 0KB 文件

    我正在尝试删除服务器上的文件 下面是我使用的代码 function ServerDel file file realpath file echo file fh fopen file w or die can t open file fcl
  • android: 库模块中的 fcm

    我在将 Firebase Cloud Messaging 集成到库模块中时面临一个奇怪的问题 我正在开发一个图书馆项目 在该项目中我需要处理来自图书馆本身的 FCM 服务器的通知 我不知道这是否可能 我遵循的步骤 我在 Firebase 控
  • Angular 的多种布局

    我正在构建一个 Angular 应用程序 但在如何处理主页方面遇到了一些障碍 主页有 90 的不同 只有标题保持不变 在那里我有显示用户登录状态的指令 为了利用路由 模板等 我理想地希望将我的 ngview 显示在示例的白色区域中 一切正常
  • 使用 git 管理 virtualenv 状态:这会导致问题吗?

    我目前已经以一种完全正确的方式设置了 git 和 virtualenv 满足我的需求 到目前为止 还没有造成任何问题 不过我知道 我的设置是非标准的 我想知道是否有人更熟悉 virtualenv 内部结构可以指出是否以及哪里可能出错 My
  • 从浏览器中删除历史点

    我们可以删除在网络浏览器中创建的历史记录点吗 或者当示例链接 某些链接 时是否可以不添加历史点 被点击并且浏览器中的 url 发生变化 您无法从浏览器历史记录中删除项目 但可以将新文档加载到窗口中并bypassjavascript 的历史
  • HNS 失败并出现错误:参数不正确

    我正在使用 Visual Studio 2017 制作一个 Docker 容器化应用程序 当首先通过 Visual Studio 运行 docker 时 出现错误 ERROR client version 1 22 is too old 通
  • 由于组合框未突出显示,如何“获取”WPF 组合框 PART_EditableTextbox?

    每次单击按钮时 我的 WPF 组合框都会填充一组不同的字符串 窗口上还有其他控件 组合框是窗口中的 第一个 顶部 但文本不会突出显示 当用户通过控件切换时 文本会突出显示 但当它是窗口上的第一个时 文本不会突出显示 也许我需要在组合框本身
  • Python:使用自定义分隔符格式化字符串[重复]

    这个问题在这里已经有答案了 EDITED 我必须使用字典中的值格式化字符串 但该字符串已经包含大括号 例如 raw string DATABASE name DB NAME 但是当然 raw string format my diction
  • 在 Active Directory 中,什么是资源?

    在 AAD node js 库的示例和测试中 00000002 0000 0000 c000 000000000000始终作为资源传递 什么是00000002 0000 0000 c000 000000000000 The 文档 https
  • 函数中的空参数不为 Null

    鉴于这个基本功能 Function TestFunction Param int Par1 string Par2 string Par3 If Par1 ne Null Write Output Par1 Par1 If Par2 ne
  • Scala 检查元素是否存在于列表中

    我需要检查列表中是否存在字符串 并调用相应接受布尔值的函数 是否可以通过一个衬垫来实现这一目标 下面的代码是我能得到的最好的 val strings List a b c val myString a strings find x gt x
  • 从Python中的文本文件中删除二进制数据

    我有一个包含一些二进制数据的文本文件 当我使用 Python 3 在文本模式下读取文件时 我收到一个 UniCodeDecodeError 编解码器无法解码字节 其中包含以下代码行 fo open myfile txt r for line
  • Yii2:scenario()模型方法

    有2个需要的功能 注册时设置密码和如果用户忘记密码则更改密码 用户注册时 密码长度必须至少为4个字符 当更改通过时 至少 5 个字符 视图对于注册和更改通行证很常见 显然 还存在两种操作 其中使用 注册 或 更改 场景 模型中的代码片段 p
  • android:以编程方式选择默认启动器

    我想弹出一个对话框 让用户选择要启动的启动器设置为默认选项 我试过 Intent home new Intent Intent ACTION DEFAULT home addCategory Intent CATEGORY LAUNCHER
  • nuget中的所有软件包都有免费使用许可证吗?

    我正在做一个需要操作 Excel 文件的项目 我找到了一个适合这项工作的库 名为 Aspose cells 它不是一个免费的库 我们应该从其网站购买其许可证才能在我们的项目中使用它 然而我发现这个库有一个nuget包 所以我有点困惑 想问以
  • 添加 .resx 文件时 WPF .net Core 3.0 编译错误

    以下工作按预期进行 VS Studio 2019 经过专业人士和社区的测试 创建新的 APF 应用程序 NET Framework 打开属性文件夹 将 Resources resx 更改为公共 创建一个新的资源文件 Resources de
  • cabal-install 配置文件的文档

    The cabal config存储 cabal install 使用的配置 我想对它进行一些黑客攻击 具体来说 安装了多个 GHC 版本 我希望有单独的文档索引 但是 除了默认文件中包含的内容之外 我找不到任何有关其语法或变量的文档 有可
  • 在运行 Kestrel 服务器时构建 .NET Core 应用程序

    在经典的 NET 应用程序中 我会设置本地 IIS 来运行指定的应用程序 我可以构建应用程序并点击端点以立即查看更改 我不需要每次都启动调试器 我想通过使用 Kestrel 服务器的 NET core 来实现这一点 我可以通过运行来运行我的
  • Android 应用程序中的静态信息在哪里安全保存?

    在我的 Android 应用程序中 我使用很少的密钥和令牌进行身份验证和初始化 我需要存储这些静态键安全地在应用程序中的某处 同时 我也需要在代码中访问它 我知道我现在使用的 SharedPreference 和 Gradle 变量 我也尝
  • 检测对象是否可重复迭代

    Does obj iter obj 暗示obj不是可重复迭代的 反之亦然 我在文档中没有看到任何这样的措辞 但根据这条评论 https stackoverflow com questions 9884132 what exactly are