类和类的实例也是可调用对象。当一个类被调用时,就生成该类的一个实例。如果该类定义了一个__init__方法,则这个方法就用来初始化新建的实例。
如果一个类定义有一个特殊的方法__call__(),那么该类的实例也可以被调用,假设x是一个可调用的类实例,x(args)调用就等同于调用x.__call__(args)。
内建函数及内建方法
可调用类型还有内建函数和内建方法。内建函数和内建方法的代码一般位于用C或者C++写的扩展模块中。下表列出了内建方法可用的属性:
属性 方法
b.__doc__ 文档字符串
b.__name__ 函数、方法名称
b.__self__ 方法所绑定的实例
b.__memebers__ 方法的属性名
对于内建函数比如len(),它的__self__是None。这表示这个函数并没有绑定给任何特殊对象。而对于内建函数x.append()来说。__self__返回x。
类 类型
class语句用来创建类。和模块类似,类也使用一个字典属性来维护自己的名称空间。访问类的属性时,比如c.x在执行行将被翻译成c.__dict__['x']。如果在类的__dict__里没有找到属性x,那么就会到该类的父类中查找。如果有多个父类,则搜索按照父类在类定义中顺序从左至右,深度优先。属性赋值如c.y=5,则总是更新c的__dict__属性,而不会更新某个父类的字典。
class对象定义的属性:
属性 描述
c.__dict__ 类c的名字空间
c.__doc__ 类c的文档字符串
c.__name__ 类c的名字
c.__module__ 类c的定义所在的模块
c.__bases__ 类c的所有父类(这是一个元组)
类实例 类型
调用一个类就会生成该类的一个实例。每个实例也有独立的名字空间。类实例有以下属性:
属性 描述
x.__dict__ 实例x的名字空间
x.__class__ 实例x所属的类
访问一个类实例x的属性时,比如x.a,解释器会先查找x.__dict__["a"],如果没有找到,则接着查询x.__class__.__dict__["a"],如果没有找到,则按照上面提到的搜索顺序继续查询该类的父类们的名字空间可如果没事没有找到,就要查看该类是否定义了__getattr__()方法,如果有这个方法就是用这个方法继续查找。
如果经过以上种种手段仍然没有找到这个属性,就引发AttributeError异常。属性赋值如x.y=5,则总是更新实例x的__dict属性,而不会更新其所属的类或者某个父类的__dict__字典。