【问题标题】:Looking a instance's class hierarchy in Python在 Python 中查看实例的类层次结构
【发布时间】:2014-10-27 14:32:02
【问题描述】:

zip 为例。 我只想知道是Iterable 还是Iterator 还是Generator

所以我把这个:

zip(x,y).__class__ 

它打印:zip
为什么类名是小写的?

import inspect
inspect.getmro(zip) 
zip.__base__ 

打印:(zip, object)
这不可能。 Python 文档说zip 返回一个iterator(或generator?),但zip 显然不是从Iterator 或类似getmro 打印出来的。

所以这两个问题,谢谢帮助。

【问题讨论】:

  • 它们是 ABC,它们不会出现在内置对象的 MRO 中...
  • 任何东西都可以是迭代器。它不必从任何特定的基类型继承;它只需要提供正确的方法。
  • Python 不太强调对象是什么类型,而是关心对象可以做什么。

标签: python oop iterator generator


【解决方案1】:

Python 中没有任何东西继承自 IteratorIterable,因为它们体现了一个协议。 Python 寻找__iter__ and __next__ methods,而不是特定的基类。任何对象都可以是可迭代对象或迭代器,只需实现这些方法即可。

zip() 是一个用 C 代码定义的内置函数,它遵循所有内置函数的命名约定;这些总是小写的;它返回的类型在这里并不完全相关,并且遵循函数名称。

collections.abc.Iterablecollections.abc.Iterator 类是抽象基类;他们实现了special hooks,如果您测试的实例或子类实现了所需的方法,则基本上返回True

zip() 既是可迭代的(它有一个__iter__ 方法)又是一个迭代器(__iter__ 返回对象本身,它有一个__next__ 方法):

>>> from collections.abc import Iterator, Iterable
>>> zip_instance = zip('')
>>> type(zip_instance)
<class 'zip'>
>>> isinstance(zip_instance, Iterator)
True
>>> isinstance((zip_instance, Iterable)
True
>>> zip_instance.__iter__
<method-wrapper '__iter__' of zip object at 0x10f2d8348>
>>> zip_instance.__iter__() is zip_instance
True
>>> zip_instance.__next__
<method-wrapper '__next__' of zip object at 0x10f2d8348>

zip() 不是生成器,因为它没有任何special generator methods

>>> hasattr(zip_instance, 'send')
False
>>> hasattr(zip_instance, 'throw')
False
>>> hasattr(zip_instance, 'close')
False

【讨论】:

  • 关于zip 而不是Zip 的注释:这就是许多内置类型的工作方式; Python和标准库只是在一定程度上符合PEP8。
  • @chepner:PEP8 声明应该遵守项目的当前约定,并且在 CPython 中所有内置函数都是小写的。因此,zip() 大部分是小写的。
  • 更重要的是,zip() 返回的东西的实际类型是无关紧要的。从来没有人看过那堂课。 zip() 是小写的,因为它被用作函数。
  • @NedBatchelder:稍微澄清了这句话以补充。
  • @WeiChing:您将 Python 表达式与动词混淆了。 zip() yields(动词),但它不使用 yield 表达式 来这样做。您使用后者来yield(动词),这会创建一个生成器函数,但并非所有yield(动词)值的迭代器都使用该表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
相关资源
最近更新 更多