类
类允许派生,可以创建一个子类,它也是类,而且继承了父类所有的特征和属性。
类体由所有声明语句,类成员定义,数据属性和函数组成。
类属性仅与其被定义的类相绑定。
python严格要求,没有实例,方法是不能被调用的。
方法必须绑定才能直接被调用。非绑定的方法可能被调用,但实例对象一定要明确给出,才能确保调用成功。
特殊的类属性
C.__name__ 类C的名字
C.__doc__ 类C的文档字符串
C.__bases__ 类C的所有父类构成的元组
C.__dict__ 类C的属性
C.__module__ 类C定义所在的模块
C.__class__ 实例C对应的类 文档字符串不能被派生类继承,也就是说派生类必须含有它们自己的文档字符串。
父类集的搜索是按顺序的,从左至右,按其在类定义父类参数时的顺序。
对类的修改仅影响到此类的字典,父类的__dict__属性不会被改动。
实例
通过调用类对象来创建实例 当类被调用,实例化的第一步是创建实例对象。一旦对象创建了,python检查是否实现了__init__()方法。
任何所需的特定操作,都需要程序员实现__init__(),覆盖它的默认行为。
__del__()析构函数要直到该实例对象所有的引用都被清除后才会执行。
__init__()构造函数只能被调用一次,一旦引用计数为0,则对象就被清除。
总结:
不要忘记首先调用父类的__del__()
调用del x不表示调用了x.__del__(),它仅仅是减少x的引用计数
__del__()未捕获的异常会被忽略掉,不要在__del__()中干与实例没任何关系的事情 除非你知道正在干什么,否则不要去实现__del__()
如果你定义了__del__,并且实例是某个循环的一部分,垃圾回收器将不会终止这个循环,需要显式调用del
实例属性
设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行。
1. 在构造器中首先设置实例属性
2. 默认参数提供默认的实例安装(带默认参数的__init__()初始化实例)
class HotelRoomCalc(object): 'Hotel room rate calculater' def __init__(self, rt, sales=0.085, rm=0.1): '''HotelRoomCalc default arguments: sales tax == 8.5% and room tax == 10%''' self.salesTax = sales self.roomTax = rm self.roomRate = rt def calcTotal(self, days=1): 'Calculate total; default to daily rate' daily = round((self.roomRate * (1 + self.roomTax + self.salesTax)), 2) return float(days) * daily>>> from hotel import HotelRoomCalc>>> sfo = HotelRoomCalc(299)>>> sfo.calcTotal()354.31>>> sfo.calcTotal(2)708.62>>> sea = HotelRoomCacl(189, 0.086, 0.058)Traceback (most recent call last): File "", line 1, in NameError: name 'HotelRoomCacl' is not defined>>> sea = HotelRoomCalc(189, 0.086, 0.058)>>> sea.calcTotal()216.22>>> sea.calcTotal(4)
3. __init__()应当返回None
实例属性与类属性
类属性难是与类相关的数据值,和实例属性不同,类属性和实例无关。
类属性即使在多次实例化中调用类,它们的值都保持不变。
类属性可以通过类或实例来访问(实例没有同名的类属性)。
类属性只能通过类来更新。
任何对实例属性的赋值都会创建一个实例属性并且对其赋值,如果类属性中存在同名的属性,则会产生意想不到的副作用。
给一个类属性同名的实例属性赋值,会有效地隐藏类属性,但一旦删除了这个实例属性,类属性又可以继续使用。 在类属性可变的(列表和字典),情况下以上不成立。