微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是python类型的“可迭代”,“迭代器”示例吗?

如何解决是python类型的“可迭代”,“迭代器”示例吗?

这是关于python(动态)类型系统如何工作的问题。我在网上阅读过一些文章,其中说要定义一个“可迭代”的类,我们需要为其定义一个__iter__函数。实际上,我们不必明确声明该类“是可迭代的”。根据其他语言的经验,我会猜到我不得不写类似的东西

class Foo extends Iterable:
   def __iter__(self):
      return self

当我测试Foo的类型及其实例之一时,我得到:

print(type(Foo))
print(type(Foo()))
print(isinstance(Foo(),collections.abc.Iterable))

输出

<class 'type'>
<class '__main__.Foo'>
True

我的问题是:python(动态)类型系统中类似“ Iterable”的概念的状态如何?我是否应该将其与类型完全相关?

解决方法

type是python调用通过class语句定义的任何对象的对象。使用Java作为参考点,type与代表类的类java.lang.Class类似。

“ Iterable”更类似于 interface 而不是 class -虽然类/类型定义了内部状态和某些方法,但是接口仅定义了那些方法。 Python并不像其他语言那样将其形式化,但是该原理在python的大多数“隐藏”方法(在两侧都带有两个下划线的方法)中都使用了。如果为类定义了特定的隐藏方法(例如__iter__()),则该类被认为是可迭代的*。

在您的示例中,您使用isinstance()来证明您的观点。 The python documentation actually has a page on collections.abc,其中详细介绍了他们的行为:

此模块提供抽象基类,可用于测试类是否提供特定接口;例如,它是否可散列还是映射。

(为强调而加粗)。

它甚至专门提到了迭代器:

class collections.abc.Iterable

提供__iter__()方法的类的ABC。

检查isinstance(obj,Iterable)会检测已注册为Iterable或具有__iter__()方法的类,但不会检测到使用__getitem__()方法进行迭代的类。确定对象是否可迭代的唯一可靠方法是调用iter(obj)

Python允许ABC类从本质上劫持了内置的isinstance()调用via defining the __instancecheck__() metaclass method,这就是为什么isinstance(Foo(),Iterable)可以返回True的原因,尽管Foo不继承自{{1} }。


*虽然这些功能的输入和输出没有像Java这样的静态类型的语言严格定义,但调用它们的内置方法却具有非常具体的期望 ,结果相同。例如,我曾经遇到一个问题,试图覆盖对象上的Iterable以返回浮点数而不是整数,因为内置__len__()试图在该对象上使用时抛出错误对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。