可调用对象
可调用对象,顾名思意,就是可以通过调用运算符 () 调用的对象.可以使用内置的 callable() 判断对象能否调用.
Python 模型文档中列出了 7 种可调用对象
- 用户使用 
def 语句或 lambda 表达式定义的函数 
- 内置函数: 使用 C (CPython)语言实现的函数,如 
len 
- 内置方法: 使用 C 语言实现的方法,如 
dict.get 
- 方法: 在类的定义体中定义的函数
 
- 类: 调用类时会运行类的 
__new__ 方法创建一个实例,然后运行 __init__ 方法进行初始化.最后将实例返回给调用方. 
- 类的的实例: 如果类定义了 
__call__ 方法,那么它的实例可以使用 () 调用.如 
1 2 3 4 5 6 7 8 9 10 11 12 13
   | class A(object):     def __init__(self, name):         self.name = name     def __call__(self):         return self.name
  >>> a = A('tom') >>> a <__main__.A object at 0x000002647592C240> >>> callable(a) True >>> a() 'tom'
   | 
 
- 生成器函数: 带有 
yield 或 yield from 表达式的函数或方法.调用生成器函数,返回生成器对象.如: 
1 2 3 4 5 6
   | def gen():     yield 'AB' >>> callable(gen) True >>> gen() <generator object gen at 0x000002647590A9E8>
   | 
 
可迭代对象
- 如果对象实现了能返回迭代器的 
__iter__ 方法,那么对象就是可迭代的 
- 实现了 
__getitem__ 方法,而且其参数是从零开始的索引,这种对象也是可迭代对象.如序列 
对可迭代对象调用 iter() 函数,会返回该对象的迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | >>> iter('aaa') <str_iterator object at 0x000002647592CB00> >>> iter([1, 2, 3]) <list_iterator object at 0x000002647592CB38> >>> iter((1, 2, 3)) <tuple_iterator object at 0x000002647592CBA8> >>> iter({1, 2, 3}) <set_iterator object at 0x0000026475928F30> >>> iter({'a' : 'b'}) <dict_keyiterator object at 0x00000264756B9868>
  class A(object):     def __init__(self, data):         self._data = data     def __iter__(self):         return iter(self._data)
  >>> a = A('string') >>> iter(a) <str_iterator object at 0x000002647592CB38>
  | 
 
可散列对象
在 Python 词汇表中,关于可散列类型的定义有这样一段话:
如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现 __hash__() 方法.
Python 中原子不可变数据类型(str,bytes 和数值类型(如 int,float))都是可散列类型,frozenset 也是可散列的,因为根据其定义,frozenset 里只能容纳可散列类型.而对于元组,当一个元组包含的所有元素都是可散列类型的情况下,它才是可散列的.
见如下示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | >>> tt = (1, 2, (30, 40)) >>> hash(tt) 8027212646858338501 >>> tl = (1, 2, [30, 40]) >>> hash(tl) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list' >>> tf = (1, 2, frozenset([30, 40])) >>> hash(tf) -4118419923444501110
  class A:     def __init__(self, data):         self.data = data     def __hash__(self):         return hash(id(self)) 
  >>> a = A('string') >>> hash(a) -2622071085978536803
   | 
 
可变对象与不可变对象
详见 Python 可变对象与不可变对象及其复制.