转载:http://www.xwy2.com/article.asp?id=119
定义
Python 的 Class 比较特别,和我们习惯的静态语言类型定义有很大区别。
1. 使用一个名为 __init__ 的方法来完成初始化。
2. 使用一个名为 __del__ 的方法来完成类似析购操作。
3. 所有的实例方法都拥有一个 self 参数来传递当前实例,类似于 this。
4. 可以使用 __class__ 来访问类型成员。
Class 有一些特殊的属性,便于我们获得一些额外的信息。
继承
Python 支持多继承,但有几点需要注意:
1. 基类 __init__ / __del__ 需显示调用。
2. 继承方法的调用和基类声明顺序有关。
成员
Python Class 同样包含类型和实例两种成员。
有几个很 "特殊" 的 "规则" 需要注意。
(1) 我们可以通过实例引用访问类型成员。因此下面的例子中 self.i 实际指向 Class1.i,直到我们为实例新增了一个成员 i。
(2) 调用类型内部方法,需要省略 self 参数。
我们可以在成员名称前添加 "__" 使其成为私有成员。
事实上这只是一种规则,并不是编译器上的限制。我们依然可以用特殊的语法来访问私有成员。
除了静态(类型)字段,我们还可以定义静态方法。
从设计的角度,或许更希望用属性(property)来代替字段(field)。
如果只是 readonly property,还可以用另外一种方式。
用 __getitem__ 和 __setitem__ 可以实现 C# 索引器的功能。
重载
Python 支持一些特殊方法和运算符重载。
通过重载 "__eq__",我们可以改变 "==" 运算符的行为。
Open Class
这是个有争议的话题。在 Python 中,我们随时可以给类型或对象添加新的成员。
1. 添加字段
2. 添加方法
3. 改变现有方法
另外,有几个内建函数方便我们在运行期进行操作。
Python Open Class 是如何实现的呢?我们看一下下面的代码。
原来,Python Class 对象或类型通过内置成员 __dict__ 来存储成员信息。
我们还可以通过重载 __getattr__ 和 __setattr__ 来拦截对成员的访问,需要注意的是 __getattr__ 只有在访问不存在的成员时才会被调用。
如果类型继承自 object,我们可以使用 __getattribute__ 来拦截所有(包括不存在的成员)的获取操作。
注意在 __getattribute__ 中不要使用 "return self.__dict__[name]" 来返回结果,因为在访问 "self.__dict__" 时同样会被 __getattribute__ 拦截,从而造成无限递归形成死循环。