print(iter(map)) # 报错:TypeError: 'type' object is not iterable
print(hasattr(map, "__iter__")) # True
map
是类(类型对象),不是实例对象,map的类是type
type中没有__iter__
__iter__
是map中的类属性:它确实存储在 map
类的字典中,是一个描述符对象
属性访问:map_obj.__iter__
Python 首先在 map_obj
实例的字典中查找 __iter__
属性(找不到)
然后在 map
类的字典中找到 __iter__
属性(这是一个槽包装器描述符)
由于这是一个描述符,Python 调用它的 __get__
方法
描述符绑定:map.__iter__.__get__(map_obj, map)
槽包装器的 __get__
方法返回一个绑定方法
这个绑定方法将 map_obj
实例与底层的 C 函数关联起来
方法调用:(...)()
对返回的绑定方法加上 ()
调用它
这实际上调用了底层的 C 函数,传入 map_obj
作为参数
# 描述符类 class MethodDescriptor: def __get__(self, instance, owner=None): if instance is None: # 当从类访问时 return self else: # 当从实例访问时,返回绑定方法 return lambda: self.__call__(instance) def __call__(self, instance): # 实际的实现 return instance # 对于迭代器,返回自身 # map 类定义(伪代码) class map: # 类属性,一个方法描述符 __iter__ = MethodDescriptor() def __init__(self, func, iterable): self.func = func self.iterable = iterable # 其他初始化代码... # 其他方法...
`hasattr(map, "__iter__")` 返回 `True` 是因为 `map` 类中有一个名为 `__iter__` 的属性,它是一个描述符(具体来说是一个槽包装器),
__iter__
是类属性:它存储在 map
类的 __dict__
中,而不是任何实例中
错误信息是 'type' object is not iterable
,这是因为:
会沿着继承链向上查找,包括检查类的元类
map
是 type
类的一个实例
查找 obj.__iter__
方法,如果 __iter__
不存在或调用失败,查找 obj.__getitem__
方法
如果不存在,检查man对象的type
类也没有 __iter__
方法,因此抛出这个错误