类型与类:
使用新式类,class a(object) 这样a就可以是type类型了,新式类
python使用__new__来构造对象,使用__init__来初始化对象,这两个是分开的,在new出的同时可以调用init方法来初始化,可以带参数;类中的每个函数(方法)都要加上self,表示为实例上的方法。self代表这个类的实例。
实例变量:是针对每个实例的变量,每个实例的变量是不同的;
类变量:是针对类的,类中的这个变量都一样;
class A(object): #这个是类变量 author = 'shizhen' #初始化方法,是什么样子,初始化就要根据这个格式 def __init__(self,page): #这个是实例变量 self.pa = page a = A(100) b = A(200) print a.pa,b.pa,a.author,b.author #动态语言的特点是可以随时给一个对象增加额外的属性,如这里,给a对象加入了book属性; a.book = 'OMG' print a.book #这里的author不是类变量,而是a对象创建了一个实例变量,外界访问时优先访问实例变量; a.author = 'lixuan' print a.author
类方法和静态方法
class A(object): author = 'shizhen' #self是实例方法,实例化后才可使用。函数的第一个要是self def __init__(self,page): self.pa = page #类方法,加@,且传入的第一个参数是cls,调用时直接用类调用 @classmethod def class_method(cls,msg): return msg #静态方法,加@,直接传入待传入参数即可,用类去声明调用 @staticmethod def static_method(msg): return msg print A.class_method("haha") print A.static_method("haha")
派生子类
python支持多继承;
class A(object): author = 'shizhen' def __init__(self,page): self.pa = page print self.pa def f(self,number): print number + 1 #继承 class B(A): def __init__(self,id): #这里是调用父类的初始化方法,新式类可用super super(B, self).__init__(id) b = B(10) b.f(10)
dir和dict---查看属性
每个对象,每个类都有自己的dict,相当于一个namespace,存放自己类的属性
dir是内建函数,可以直接调用,返回所有对象中的属性,包括父类的属性,返回一个序列,只说明属性有哪些;
dict则是类自带方法,返回当前类中所有的属性,不包括父类的属性,返回的是个字典,包括属性以及其值;
class A(object): author = 'shizhen' def __init__(self,page): self.pa = page a = A(10) #这个是a这个实例的字典,在a创建后,只有10这个元素,因此字典中只有10 print a.__dict__ #调用对象自己的方法查看当前类的属性 print A.__dict__ print dir(A) print dir(a) #文档方法 A.__doc__
析构函数
__del__:当对象的引用技术为0的时候,python的解释器会自动调用这个函数,如果是继承机构的话,会del先释放父类对象;
可见性
__id表示private,只有类中可以调用;
多重继承
新式类采用的是广度优先的算法;
*attr
class A(object): author = 'shizhen' def __init__(self,page): self.__pa = page def f(self): print "hello" a = A(10) #这个是获取一个对象,把里面的方法拿出来,供外界使用 getattr(a,'f')() #判断a类中是否有这个方法 print hasattr(a,'f') #还有delattr和setattr,删除和设置,这也是动态语言的特点
这个方法不仅适用于类,同时也适用于实例
内建函数
issubclass(sub,sup) 判断是否为子类
isinstance(obj,classType) 判断是否为类的实例
练习题:
实现一个(x,y)的Point类表示坐标上的点(X,Y),如果在构建Point对象的时候没有提供x,y,则默认是原点, 实现一个Retangle类表示一个矩形,使用四个点作为这个矩形的构造函数的参数,实现一个area的实例方法返回该矩形的面积
class Point(object): def __init__(self,x=0,y=0): self.xpoint=x self.ypoint=y class Retangle(object): def __init__(self,point1,point2,point3,point4): self.point1 = point1 self.point2 = point2 self.point3 = point3 self.point4 = point4 def findCK(self,point1,point2,point3,point4): self.length = abs(point1.xpoint-point2.xpoint) self.width = abs(point2.ypoint-point3.ypoint) def area(self): self.findCK(self.point1,self.point2,self.point3,self.point4) self.result = self.length*self.width return self.result p1=Point(-1,2) p2=Point(3,2) p3=Point(3,-1) p4=Point(-1,-1) re = Retangle(p1,p2,p3,p4) print re.area()
2.实现一个单例(singleton),即所有类的实例实际都指向同一个对象,也可以理解为,所有的id返回都是同样的内存地址。
class singleton(object): #在new上做分配,保证只分配一次空间 def __new__(cls): if not hasattr(cls,'_instance'): original = super(singleton, cls) cls._instance = original.__new__(cls) return cls._instance s = singleton() p = singleton() s.page = 10 print p.page
new是分配空间时用的,init是分完之后初始化用的