Python笔记(5)类__方法与继承

方法

类方法@classmethod,实例方法,静态方法@staticmethod,特殊方法,__init__

形式上的区别:调用是通过类和实例进行,不能直接调用,有自己的特殊参数,如__init__有self,类方法有参数class,有自己的声明方式。

实质上的区别:类方法与类绑定,实例方法绑定实例,静态方法无绑定(和函数一样,只不过用类和实例进行调用),特殊方法某些场景会自动调用。

特殊方法

数字计算:加减乘除都是通过特殊方法来实现的,round是四舍五入。

调用方法:str()转化成字符串,len()长度,bool判断真假。

比较大小:lt是less than,le是less equal,gt是great than,ge是great equal,ne是not equal。

集合访问:setslice,getslice是切片操作,getitem,setitem是字典的item访问,contains是包含(就是if a in b)的时候用。

迭代器,属性访问,类生产,前面有说过了。

class Point(object):
    def __init__(self,x,y):
        self.x = float(x)
        self.y = float(y)
    def __sub__(self, other):
        assert isinstance(other,Point)
        return Point(self.x-other.x,self.y-other.y)
    def __add__(self, other):
        assert isinstance(other,Point)
        return Point(self.x+other.x,self.y+other.y)
    def __mul__(self,factor):
        return Point(self.x*factor, self.y*factor)
    def __div__(self,factor):
        return Point(self.x/factor, self.y/factor)    
        
    @property    
    def xy(self):
        return (self.x,self.y)
    
    def __str__(self):
        return "x={0},y={1}".format(self.x,self.y)
    def __repr__(self):
        return str(self.xy)
        
if __name__ == '__main__':
       
    a = Point(50,60)
    b = Point(30,40)
    
    print a-b
    print a+b
    print a*2
    print a/2
a
Out[5]: (50.0, 60.0)

print a
x=50.0,y=60.0

这里重载了加减乘除。python中运算符重载很方便,只要你重新写一下特殊方法。

__str__是当你调用print的时候他会自动调用__str__。

__repr__是给计算机看的,比如你输入a 他应该输出地址什么的,但是因为这里重写了repr所以他会输出我们想要的(self.x,self.y)。

继承

通过已有的类,生产新的类,新的类具有父类的属性和方法,实现代码的重用。

单一继承比较简单,就是直接继承属性和方法。

继承顺序

MRO method resolution order 方法的解析顺序。

继承顺序,经典类是深度优先,新式类是C3算法。

经典类A是优先于C的,新式类C优先于A。

class A:
    a=1
    b=1

class B(A):
    a=2
    
class C(A):
    a=3
    b=3
    c=3
        
class D(B,C):
    pass    

if __name__=="__main__":
    d=D()
import inspect

inspect.getmro(D)
Out[15]: 
(<class __main__.D at 0x07A14148>,
 <class __main__.B at 0x07A140D8>,
 <class __main__.A at 0x07A140A0>,
 <class __main__.C at 0x07A14110>)
d.a
Out[17]: 2

d.b
Out[18]: 1

d.c
Out[19]: 3

d的a属性继承自B,b属性继承自A,c属性继承自C,如果A中已经定义了c,则C对于c属性的重写则永远都不会访问到。新式类曾经有一段时间使用深度优先,这样解决了无法访问重写的问题,但是他违背了查找的顺序性。

新式类:

class A(object):
    a=1
    b=1
#只要修改A(object)就好了,其他不变。
inspect.getmro(D)
Out[22]: (__main__.D, __main__.B, __main__.C, __main__.A, object)
print d.a,d.b,d.c
2 3 3

这里a属性继承自B,bc属性继承自C。并且新式类D中有mro的特殊方法,经典类没有。

D.__mro__
Out[26]: (__main__.D, __main__.B, __main__.C, __main__.A, object)

C3算法,用的是一个拓扑排序并且为了顺序性,拓扑排序的时候出现两个入度为0则取左边的。可以参考http://python.jobbole.com/85685/。

方法调用
class A:
    def test(self):
        print "A's test"

class B(A):
    def test(self):
        print "B's test"
        A.test(self)
class C(A): def test(self): print "C's test" A.test(self) class D(B,C): def test(self): print "D's test" B.test(self) C.test(self) if __name__=="__main__": a=D() a.test()
D's test
B's test
A's test
C's test
A's test

为了避免父类函数被重复调用,所以有了Super。

Super是一个类,不是函数。Super只在新式类里有。super(instance,self)。

class A(object):
    def test(self):
        print "A's test"

class B(A):
    def test(self):
        print "B's test"
        super(B,self).test()
    
class C(A):
    def test(self):
        print "C's test"
        super(C,self).test()
        
class D(B,C):
    def test(self):
        print "D's test"
        super(D,self).test()

    
if __name__=="__main__":
    a=D()
    a.test()
D's test
B's test
C's test
A's test
#只出现一次,广度优先。
 
多态  

   多态是不同类的相同方法,相同参数,不同的功能。不同的参数是重载(args,kwargs)。

   Python中并不需要像java那样写好接口,规定什么属性,python是一种动态语言,参数在传入之前是无法确定参数类型的。所以python会假设存在,然后直接调用,如果没有就会报错。可以参考http://blog.csdn.net/shangzhihaohao/article/details/7065675。

  Python是动态强类型语言。

 

转载于:https://www.cnblogs.com/zephyr-1/p/5698562.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值