zoukankan      html  css  js  c++  java
  • python之类的继承

    在继承当中我们将父类称为:父类,基类,超类

    将子类称为:子类,派生类,继承类

    子类和父类是is的关系。

    假如:p1是父类的一个实例,我们可以说p1是父类,但是不能说是子类。

    p2是子类的一个实例,我们能说p2是子类,也能说p2是父类。

    >>> class Person(object):
        def __init__(self,name,gnder):
            self.name = name
            self.gender = gender
    
            
    >>> class Student(Person):
        def __init__(self,name,gender,school,score):
            super(Student,self).__init__(name,gender)
            self.school = school
            self.score = score

    这里面就是Student从Person父类继承了,这里要注意的是

    super(Student,self).__init__(name,gender)是一个用来初始化父类的语句

     ————————————————————————————————————————————————————

    判断类型:

    函数isinstance()可以判断一个变量的类型,既可以用在Python内置的数据类型如str、list、dict,也可以用在我们自定义的类,它们本质上都是数据类型。

    >>> class Person(object):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
    
            
    >>> class Student(Person):
        def __init__(self,name,gender,score):
            super(Student,self).__init__(name,gender)
            self.score = score
    
            
    >>> class Teacher(Person):
        def __init__(self,name,gender,course):
            super(Teacher,self).__init__(name,gender)
            self.course = course
    
            
    >>> p = Person('Tim','Male')
    >>> s = Student('Bob','Male',88)
    >>> t = Teacher('Alice','Female','English')
    >>> isinstance(s,Person)
    True
    >>> isinstance(s,Student)
    True
    >>> isinstance(s,Teacher)
    False

    从上面的返回结果可以看出,s属于person类和student类,但是不属于teahcer类。

    ——————————————————————————————————————————

    多态性

    >>> class Person(object):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
    
            
    >>> class Person(object):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
        def whoAmI(self):
            return 'I am a Person,my name is %s' %self.name
    
        
    >>> class Student(Person):
        def __init__(self,name,gender,score):
            super(Student,self).__init__(name,gender)
            self.score = score
        def whoAmI(self):
            return 'I am a Student,my name is %s' % self.name
    
        
    >>> class Teacher(Person):
        def __init__(self,name,gender,course):
            super(Teacher,self).__init__(name,gender)
            self.course = course
        def whoAmI(self):
            return'I am a Teacher,my name is %s'% self.name
    
        
    >>> def who_am_i(x):
        print x.whoAmI()
        
    SyntaxError: invalid syntax
    >>> def who_am_i(x):
        print (x.whoAmI())
    
        
    >>> p = Person('Tim','Male')
    >>> s = Student('Bob','Male',88)
    >>> t = Teacher('Alice','Female','English')
    >>> who_am_i(p)
    I am a Person,my name is Tim
    >>> who_am_i(s)
    I am a Student,my name is Bob
    >>> who_am_i(t)
    I am a Teacher,my name is Alice

    这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

    由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可:

    这是动态语言静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

    ——————————————————————————————————————————————————————————————————

    多重继承

    子类可以从多个父类继承。

    >>> class A(object):
        def __init__(self,a):
            print ('init A...')
            self.a = a
    
            
    >>> class B(A):
        def __init__(self,a):
            super(B,self).__init__(a)
            print ('init B...')
    
            
    >>> class C(A):
        def __init__(self,a):
            super(C,self).__init__(a)
            print('init C...')
    
            
    >>> class D(B,C):
        def __init__(self,a):
            super(D,self).__init__(a)
            print ('init D...')
    
            
    >>> d = D('d')
    init A...
    init C...
    init B...
    init D...

    多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用。

    举个例子,Python的网络服务器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服务器运行模式有 多进程ForkingMixin 和 多线程ThreadingMixin两种。

    要创建多进程模式的 TCPServer:

    class MyTCPServer(TCPServer, ForkingMixin)
        pass

    要创建多线程模式的 UDPServer

    class MyUDPServer(UDPServer, ThreadingMixin):
        pass

    如果没有多重继承,要实现上述所有可能的组合需要 4x2=8 个子类。

    ————————————————————————————————————————————————

    获取对象信息

    我们获取对象信息除了isinstance()之外还有type()

    >>> class D(B,C):
        def __init__(self,a):
            super(D,self).__init__(a)
            print ('init D...')
    
            
    >>> d = D('d')
    init A...
    init C...
    init B...
    init D...
    >>> type(123)
    <class 'int'>
    >>> type(d)
    <class '__main__.D'>

    其次,可以用 dir() 函数获取变量的所有属性:

    >>> dir(123)
    ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
    >>> dir(d)
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']

    dir()返回的属性是字符串列表,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr()  setattr( )函数了:

    >>> class Student(object):
        def __init__(self,name):
            self.name = name
    
            
    >>> a = Student('Dean')
    >>> getattr(a,'name')
    'Dean'
    >>> setattr(a,'name','Adam')
    >>> a.name
    'Adam'
    >>> getattr(a,'age')   # 获取age属性,但是属性不存在,报错:
    Traceback (most recent call last):
      File "<pyshell#39>", line 1, in <module>
        getattr(a,'age')   # 获取age属性,但是属性不存在,报错:
    AttributeError: 'Student' object has no attribute 'age'
    >>> getattr(s, 'age', 20)  # 获取age属性,如果属性不存在,就返回默认值20:
    20
     
  • 相关阅读:
    语言只是个工具
    最近学到的一点东西
    iBeacon开发
    马上着手开发Mac应用程序
    Text Kit入门
    Text Kit进阶
    Web Notification
    Objective-C异步编程
    Clang Language Extensions
    黑客与画家
  • 原文地址:https://www.cnblogs.com/chang1203/p/5844235.html
Copyright © 2011-2022 走看看