• 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是动态强类型语言。

  • 相关阅读:
    原生js实现Ajax请求,包含get和post
    JSP和Servlet的关系
    框架、框架模式和设计模式
    Java技术综述
    传输层和网络层区别(形象解释)
    Vue基本用法:过滤器、生命周期钩子函数和利用webpack 生成项目
    Vue基本用法:组件
    Vue基本用法:计算属性、监听器和表单输入绑定
    Vue基本用法:模板语法和指令系统
    win10想说爱你不容易——安装.net3.5也是一个坑(已有完美解决方法)
  • 原文地址:https://www.cnblogs.com/zephyr-1/p/5698562.html
Copyright © 2020-2023  润新知