类型与类:

使用新式类,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先释放父类对象;


可见性

__spacer.gifid表示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) 判断是否为类的实例


练习题:

  1. 实现一个(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是分完之后初始化用的