zoukankan      html  css  js  c++  java
  • Python-面向对象编程

    Python-面向对象编程

          函数式编程适合用于各个函数之间是独立且无共用的数据,没有对象和类的概念

    面向对象编程中各个函数公用一组数据,此编程方式的落地需要使用“类”和“对象”来实现,所以,面向对象编程其实就是对“类”和“对象”的使用

    一般在python中,全部采用面向对象编程或者面向对象编程和函数式编程混合使用 

    • 类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
    • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
    • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    • 实例变量:定义在方法中的变量,只作用于当前实例的类。
    • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例如,Dog是一个Animal)。
    • 实例化:创建一个类的实例,类的具体对象。
    • 方法:类中定义的函数。
    • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

    1、类

    现实世界中所有对象都归属于某种对象类型,同一类型的对象具有共同的特征与行为。用class这个关键词来进行对对象类型的定义,他是面向对象程序设计语言的基本概念。类定义好之后,我们就可以像使用其他数据类型一样声明该类的变量并创建该变量所指向的对象,然后通过该变量调用对象的方法实现对对象的操作

    将类实例化就得到了现实世界实体的面向对象的映射-对象

    类描述了同一类对象都具有的数据和行为

    1.1:创建类

    使用class语句来创建一个新类,class之后为类的名称,类名后有一括号,括号中为基类(可以有多个基类)然后以冒号结尾。

    classClassName(BaseClass1,BaseClass2,...):

    'optional class documentation string'#类的帮助信息

    class_suite #类体

    类的帮助信息可以通过ClassName.__doc__查看。

    Class_suite由类成员、方法、数据属性组成。

    class Foo:

    def Bar(self):

    print 'Bar'

    def Hello(self, name):

    print 'I am %s' %name

    # 根据类Foo创建对象obj

    obj=Foo()

    obj.Bar()   #执行Bar方法

    obj.Hello('pangwei')    #执行Hello方法

    1.2:访问类的实例方法或者属性

    访问对象的属性及方法,需要使用(.)来访问。如果访问类变量,既可以直接使用类名称访问,也可以用类的实例名称访问。

    注意:在实例化类时,不需要再显示写self参数了,会默认带入,表示指向实例本身。

    class Employee (object):

    #object是Employee基类,所有类都是继承自基类object

    empCount= 0  

    #类变量,也叫静态变量,它的值将在这个类的所有实例之间共享。可以在内部类或外部类使用Employee.empCount访问

    def __init__(self, name, salary) :

    #类的构造函数,只要创建类的实例,就会调用这个方法,如果没有显示定义这个方法,会默认给一个空的构造方法

    self.name = name

    self.salary= salary

    Employee.empCount+= 1

    def displayCount(self) :

    #类方法,参数self代表实例本身,所有类方法中都必须有self参数,并写在第一个参数位置

    print "total employee ",Employee.empCount

    def displayEmployee(self) :

    print "name :",self.name , ", salary :", self.salary

    emp1=Employee("pangwei","2000")

    emp2=Employee("zhangsan","1000")

    emp1.displayEmployee()

    emp2.displayEmployee()

    print "Total Employee %d" % Employee.empCount

    执行结果:

    E:>python 037test.txt

    name : pangwei , salary : 2000

    name : zhangsan , salary : 1000

    Total Employee 2            #创建了两个实例,调用了两次构造函数

    2、封装

    封装:将内容封装到某个地方,以后再去调用被封装在某处的内容。减少重复代码的编写,复用代码;将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装

    class Foo:

    def__init__(self, name, age):

    self.name=name

    self.age=age

    def detail(self):

    print self.name

    print self.age

    obj1=Foo('pangwei',18)

    obj2=Foo('zhangsan',18)

    #self是一个形式参数,当执行obj1=Foo('pangwei',18)时,self等于obj1,当执行obj2=Foo('zhangsan',18)时,self等于obj2

    #所以,内容其实是被封装到了对象obj1和obj2中,每个对象中都有name和age属性

    调用:调用被封装的内容时,有两种情况

    • 通过对象直接调用(对象:属性名)
    • 通过self间接调用(需要通过self间接调用被封装的内容)

    print obj1.name

    #直接调用obj1对象的name属性

    print obj1.age

    #直接调用obj1对象的age属性

    obj1.detail()

    obj2.detail()

    # Python默认会将obj1传给self参数,即:obj1.detail(obj1)

    #所以,此时方法内部的self =obj1,即:self.name 是pangwei;self.age是18

    封装例子:

    #coding=utf-8

    class Animal(object):

        def __init__(self, name):

        #构造方法一个对象创建后会立即调用此方法

            self.Name= name

            print self.Name

        def accessibleMethod(self):

        #绑定方法对外公开

            print "I have a self! current name is:"

            print self.Name

            print "the secret message is:"

            self.__inaccessible()

        def __inaccessible(self):

        #私有方法对外不公开以双下划线开头

            print "U cannot see me..."

        @staticmethod

        def staticMethod():

            # self.accessibleMethod()

            #在静态方法中无法直接调用实例方法直接抛出NameError异常

            print "this is a static method"

        def setName(self,name): #访问器函数

            print "setName:"

            self.Name=name

        def getName(self): #访问器函数

            print "getName:"

            return self.Name

    a = Animal("learns")

    print a.getName()

    a.setName("sr")

    print "new name:",a.getName()

    a.staticMethod()

    #执行结果

    E:>python 0319test.txt

    learns

    getName:

    learns

    setName:

    new name: getName:

    sr

    this is a static method

    3、类成员

    类成员可以分成三大类:字段、方法和属性。

    字段包括普通字段和静态字段;方法包括普通方法,类方法和静态方法;属性包括普通属性

    3.1字段

    字段包括普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,普通字段属于对象,静态字段属于类。

    静态字段定义在方法之外,在内存中只保留一份,可以通过classname.field(类名.字段名)访问使用

    普通字段在每一个对象中都保存一份,一般定义在构造函数中,需要实例化对象,才能访问使用

    #encoding=utf-8

    class Province:

    # 静态字段

    country = u'中国'

    def __init__(self, name):

    # 普通字段

    self.name = name

    # 直接访问普通字段

    obj= Province(u'河北省')

    print obj.name

    # 直接访问静态字段

    print Province.country

    执行结果:

    E:>python py.txt

    河北省

    中国

     

    3.2方法

    方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类(非对象),在内存中也只保存一份。区别在于方法的调用者不同,调用方法时自动传入的参数不同。

    普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;

    类方法:由类调用,至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls,定义时需要在方法上方加上类方法修饰器@classmethod;

    静态方法:由类调用,无默认参数,定义时需要在方法上方加上静态方法修饰器@staticmethod;

    #coding=utf-8

     

    class Method():

        def __init__(self,name):

            self.name=name

     

        def nomalmethod(self):

            print u"调用普通方法"

     

        @classmethod     #类方法修饰器

        def classmethod(cls):

            print u"调用类方法"

     

        @staticmethod    #静态方法修饰器

        def staticmethod():

            print u"调用静态方法"

     

    obj=Method("zhangsan")

    #调用普通方法

    obj.nomalmethod()

    #调用类方法

    Method.classmethod()

    #调用静态方法

    Method.staticmethod()

    执行结果:

    E:>python 037test.txt

    调用普通方法

    调用类方法

    调用静态方法

    3.3属性

    python中属性就是普通方法的变种,如果python中没有属性,方法完全可以代替其功能,访问属性时可以制造出和访问字段完全相同的假象,

    3.3.1属性的定义和调用

    定义属性时,在普通方法的基础上添加@property装饰器;当属性仅有一个self参数时,无需括号;属性有两种定义方式:经典类的属性和新式类的属性

    经典类属性:

    #coding=utf-8

     

    class Property():   

        def filed(self):

            print u"普通方法"

     

        @property   #属性修饰器

        def prop(self):

            return u"属性"

     

    obj=Property()

    obj.filed()

    print obj.prop   #调用属性

     

    #执行结果

    E:>python 037test.txt

    普通方法

    属性

    新式类属性:

    新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

    #coding=utf-8

    class Goods(object):

        @property

        def size(self):

            print u"size属性"

       

        @size.setter

        def size(self,value):

            print "set size:",value

        @size.deleter

        def size(self):

            print "del size"

    obj=Goods()

    obj.size   #自动执行@property修饰的size方法,并获取方法的返回值

    obj.size=43  #自动执行@size.setter修饰的size方法,并将43赋值给方法的参数

    del obj.size   #自动执行@size.deleter修饰的size方法

    #执行结果

    E:>python 037test.txt

    size属性

    set size: 43

    del size

    3.3.2属性的添加、删除和修改;类的内置属性

    • 动态直接添加、删除和修改类属性

    #coding=utf-8

    class Employee (object):

    #所有员工基类

    empCount = 0

    def __init__(self, name, salary) :

    #类的构造函数

    self.name = name

    self.salary = salary

    Employee.empCount += 1

    def displayCount(self) :

    print "total employee ",Employee.empCount

    def displayEmployee(self) :

    print "name :",self.name , ", salary :", self.salary

    #创建Employee类的实例对象

    emp1 = Employee("SR", 10000)

    emp1.displayCount()

    emp1.displayEmployee()

    emp1.salary = 20000  #修改属性(普通变量)salary

    print emp1.salary

    emp1.age = 25    #添加属性age

    print emp1.age

    emp1.displayEmployee()

    Employee.empCount=100   #修改类变量Employee.empCount

    print Employee.empCount

    del emp1.age    #删除age属性

    #执行结果

    E:>python 037test.txt

    totalemployee 1

    name : SR , salary : 10000

    20000

    25

    name : SR , salary : 20000

    100

    • 使用函数添加、删除和修改类属性

    可以使用以下函数来操作对象的属性:

    1、getattr(obj, name[, default]) :访问对象的属性,如果存在返回对象属性的值,否则抛出AttributeError异常。

    2、hasattr(obj,name) : 检查是否存在某个属性,存在返回True,否则返回False。

    3、setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性,该函数无返回值。若存在则更新这个值

    4、delattr(obj, name) :删除属性,如果属性不存在则抛出AttributeError异常,该函数也无返回值。

    • python的内置类属性

    1、__dict__:类的属性(包含一个字典,由类的数据属性组成)

    2、__doc__:类的文档字符串,也就是类的帮助信息

    3、__name__:类名

    4、__module__:类定义所在的模块(类的全名是”__mian__.className”,如果类位于一个导入模块mymod中,那么className.__module__等于mymod)

    5、__bases__:类的所有父类(包含了所有父类组成的元组)

     

    #coding=utf-8

    class Dogs(object):

        def __init__(self,name,age):

            self.name=name

            self.age=age

        def runn(self):

            print "dog run"

    obj=Dogs("zangao",3)

    #判断属性是否存在

    if hasattr(obj,"name"):

        print u"name属性存在"

    else:

        print u"name属性不存在"

    #获取name属性的值

    try:

        a=getattr(obj,"name")

        print u"name 的属性值是:",a

    except Exception,e:

        print e

    #获取一个并不存在的wight属性的值  

    try:

        a=getattr(obj,"wight")

        print u"wight的属性值是:",a

    except Exception,e:

        print e

    #新增一个属性wight

    setattr(obj,"wight",50)

    try:

        a=getattr(obj,"wight")

        print u"新添加的wight属性值是:",a

    except Exception,e:

        print e

    try:

        delattr(obj,"wight") #删除属性

    except Exception,e:

        print e

    else:

        if hasattr(obj,"wight"):

            print u"wight属性仍然存在"

        else:

            print u"wight属性已经被删除"

    #执行结果

    E:>python 037test.txt

    name属性存在

    name 的属性值是: zangao

    'Dogs' object has no attribute 'wight'

    新添加的wight属性值是: 50

    wight属性已经被删除

    python内置类属性

    print "Dogs.__doc__:",Dogs.__doc__  #打印类的文档字符串

    print "Dogs.__name__:",Dogs.__name__    #打印类名

    print "Dogs.__module__:",Dogs.__module__  #打印类定义所在的模块

    print "Dogs.__bases__:",Dogs.__bases__   #打印类的所有父类

    print "Dogs.__dict__:",Dogs.__dict__       #打印类的属性,一个字典

    #执行结果

    Dogs.__doc__: help dogs

    Dogs.__name__: Dogs

    Dogs.__module__: __main__

    Dogs.__bases__: (<type 'object'>,)

    Dogs.__dict__: {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Dogs' objects>, '__weakref__': <attribute '__weakref__' of 'Dogs' objects>, '__doc__': 'help dogs', '__init__': <function __init__ at 0x0000000002835BA8>, 'runn': <function runn at 0x0000000002835C18>}

    3.3.3私有属性、私有方法

    类中的方法名前后都有两个下划线,表示Python的内置方法,如__init__();

    类中的方法名前面有两个下划线,表示是Python中的私有方法,不能在类外部调用,如__setId();在类内部调用语法:self.__setId。

    类中的属性前有两个下划线表示声明该属性为私有属性,不能在类的外部被使用或直接访问,如__name,在类内部的方法中使用时的语法:self.__name,self为实例化对象,__name为属性名;虽然Python不允许实例化的类从外部访问私有数据,但是可以使用self._className__name访问私有属性。Python的语法并不是那么严格的能够保证私有变量不被随意改动

    #coding=utf-8

    class Dogs(object):

        """help dogs"""

        __dogscount=0

        __dogsname="taidi"  #私有属性

        def __init__(self,name):

            self.name=name

            self.__inName="moka"  #私有属性

        def __setName(self):   #私有方法

            self.__dogsname="hasiqi"

      

        def play_game(self):

            self.__setName()     #调用私有方法

            self.__dogscount+=1

            print "__dogsname:",self.__dogsname

            print "__dogscount:",self.__dogscount

            print "__inNane:",self.__inName

    d=Dogs("zao")

    print u"在类外直接通过实例访问私有属性"

    try:

        print d.__dogsname

    except Exception,e:   

        print e

    d.play_game()

    print u"使用另一种方法访问私有属性"

    try:

        print d._Dogs__dogsname

        print d._Dogs__inName

    except Exception,e:   

        print e

    print u"在类外直接通过实例访问私有方法"

    d.__setName()

    #执行结果

    E:>python 0314test.txt

    在类外直接通过实例访问私有属性

    'Dogs' object has no attribute '__dogsname'

    __dogsname: hasiqi

    __dogscount: 1

    __inNane: moka

    使用另一种方法访问私有属性

    hasiqi

    moka

    在类外直接通过实例访问私有方法

    Traceback (most recent call last):

      File "0314test.txt", line 38, in <module>

        d.__setName("hasiqi")

    AttributeError: 'Dogs' object has no attribute '__setName'

    4、继承

    面向对象的编程带来的主要好处之一是代码的重用,通过继承机制是实现这种重用的方法之一。对于面向对象的继承来说,其实就是将多个类公有的方法提取到父类中,子类仅需要继承父类而不必一一实现每个方法,以此来实现代码的重用。

    基类名写在括号里,如果在继承元组中列出了一个以上的基类,那么它就被称作“多重继承”。

    class 派生类名(基类名1[,基类名2……]):

        pass

    在继承中基类的构造(__init__())方法不会被自动调用,它需要在其派生类的构造方法中专门调用,子类不会继承基类的构造方法。

    在调用基类的方法时,需要加上基类的类目前缀,且需要带上self参数变量,在类中调用普通函数时并不需要带上self参数。

    Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找(先在本类中查找,找不到再去基类中找)。

    子类只继承父类所有公有的属性和方法并且可以在子类中通过基类名来调用,而对于私有的属性和方法,子类是不继承的。

    4.1单继承

    继承例子1

    #coding=utf-8

    class Animal():

        """father obj Animal"""

        wight=0

        def eat(self):

            print "%s eat"%self.name

            Animal.wight+=2

        def drink(self):

            print "%s drink"%self.name

            Animal.wight+=1

        def shit(self):

            print "%s shit"%self.name

            Animal.wight-=2

        def pee(self):

            print "%s pee"%self.name

            Animal.wight-=1

    class Dogs(Animal):

        def __init__(self,name):

            self.name=name

        def cry(self):

            print u"%s汪汪叫"%self.name

    class Cats(Animal):

        def __init__(self,name):

            self.name=name

        def cry(self):

            print u"%s喵喵叫"%self.name

    d1=Dogs(u"小明家的藏獒")

    d1.cry()     #调用自身的cry方法

    d1.eat()     #调用父类的eat方法

    d2=Dogs(u"小黑家的哈士奇")

    d2.cry()

    d2.drink()

    c1=Cats(u"小强家的加菲")

    c1.cry()

    c1.pee()

    print "Animal.wight:",Animal.wight  #子类调用父类方法可以操作父类类变量

    #执行结果

    E:>python 0316test.txt

    小明家的藏獒汪汪叫

    小明家的藏獒 eat

    小黑家的哈士奇汪汪叫

    小黑家的哈士奇 drink

    小强家的加菲喵喵叫

    小强家的加菲 pee

    Animal.wight: 2

    继承例子2,子类有无构造方法__init__

    #coding=utf-8

    class Animal():

        """father obj Animal"""

        wight=0

        def __init__(self,name):

            print u"基类构造方法,用于初始化工作"

            self.name=name

        def animal_action(self):

            print "%s running"%self.name

        def set_animal_wight(self):

            Animal.wight+=100

        def get_animal_wight(self):

            print "Animalwight:",Animal.wight

    class Dogs(Animal):

        def __init__(self,name):

            print u"子类构造方法,用于初始化工作"

            self.name=name

        def dog_cry(self):

            print u"%s汪汪叫"%self.name

            Animal.animal_action(self)    #调用基类的方法,需要加上参数self

            Animal.set_animal_wight(self)

    class Cats(Animal):

        """have no __init__"""

        #没有实现__init__方法,则会调用基类的__init__方法

        def cat_cry(self):

            print u"%s喵喵叫"%self.name

            self.animal_action()    #子类调用自己从父类那继承过来的父类的方法

            self.set_animal_wight()

    d1=Dogs(u"小黑家的大黄")

    d1.dog_cry()                  #子类调用自己本身的方法

    d1.get_animal_wight()       #子类调用父类的方法

    c1=Cats(u"小明家的波斯")  #Cats子类没有构造方法,会调用基类的构造方法,执行基类的__init__()

    c1.cat_cry() 

    c1.get_animal_wight()

    #执行结果

    E:>python 0316test.txt

    子类构造方法,用于初始化工作

    小黑家的大黄汪汪叫

    小黑家的大黄 running

    Animalwight: 100

    基类构造方法,用于初始化工作

    小明家的波斯喵喵叫

    小明家的波斯 running

    Animalwight: 200

    从上述例子可以看出,子类调用基类的方法有两种

    1、          Animal.animal_action(self):基类名.基类方法名,需要注意的是,这种调用方法必须将self作为第一参数传进去,表示指向这个类的实例本身,这种方法多用于方法重写。

    2、          self.animal_action():直接用self去调用基类的方法,因为子类继承了基类,子类就拥有了基类所有的公有方法和属性,所以此时基类的方法和属性就相当于子类自己了,可以直接用self去调用实例的方法而不用在传入self参数

    4.2调用父类的__init__方法

    从上面例子可以看出,子类如果有自己的__init__方法时,基类的构造方法不会被主动继承,所以基类构造函数中初始化的一些属性在子类中是不具有的,这时候如果子类想用这些属性,只有两种方法,第一种是在子类构造方法中再写一次这些属性;第二种是调用父类的__init__方法完成,一般用第二种方法

    子类调用基类的构造函数有两种方法,基本语法如下:两次参数列表中的self参数都是必不可少的,如果基类的构造方法中有除了self参数外别的参数,调用时,也必须传入同等数量、同等类型的参数。

    1、super(subclassName, self).__init__( [parameter1[,parameter2....]]) 

    2、superclassName.__init__(self, [parameter1[,parameter2....]])

    1、super(subclassName, self).__init__( [parameter1[,parameter2....]]) 方法

    #coding=utf-8

    class A(object):

        name=''

        def __init__(self):

            self.name='stupang'

        def getName(self):

            return 'A ' + self.name

    class C(A):

        def __init__(self):

            super(C, self).__init__() #super函数调用基类构造方法

    if __name__=='__main__': 

        c = C()

        print c.getName()

    #执行结果

    E:>python 0319test.txt

    A stupang

    2、superclassName.__init__(self, [parameter1[,parameter2....]])

    #coding=utf-8

    class UniversityMember(object):

        def __init__(self, name, age):

            self.name = name

            self.age= age

        def getName(self):

            return self.name

        def getAge(self):

            return self.age

    class Student(UniversityMember):

        def __init__(self, name, age,sno, Department):

            #注意要显示调用父类构造方法,并传递参数self

            UniversityMember.__init__(self, name, age)

            self.sno = sno

            self.Department= Department

        def getSno(self):

            return self.sno

        def getDepartment(self):

            return self.Department

    s = Student("stupang", "18", "CS", 18)

    print s.name, s.age

    s.name = 'superman'

    print s.name

    print s.getName()  #调用父类方法

    print s.getAge()

    #执行结果

    E:>python 0319test.txt

    stupang 18

    superman

    superman

    18

    4.3类间的关系判断issubclass()/isinstance()

    issubclass(class1,class2):为布尔判断,如果class1是class2的子类,这返回True,否则返回False;其中参数class1和class2必须是两个类,否则会报TypeError: issubclass() arg 1 must be a class

    #coding=utf-8

    class UniversityMember(object):

        pass

    class Student(UniversityMember):

        pass

    if issubclass(Student, UniversityMember) :

        print u"Student类是UniversityMember类的子类"

    else :

        print u"Student类不是UniversityMember类的子类"

    #执行结果

    E:>python 0319test.txt

    Student类是UniversityMember类的子类

    isinstance(i,class):为布尔判断,判断实例i是否为class或者class子类的实例,是则返回True,否则返回False,其中class必须是一个类,否则会报TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

    class UniversityMember(object):

        pass

    class Student(UniversityMember):

        pass

    um = UniversityMember() #创建父类的实例

    s = Student() #创建子类的实例

    if isinstance(um, UniversityMember) :

        print u"um是UniversityMember类或其子类的实例对象"

    else :

        print u"um不是UniversityMember类或其子类的实例对象"

    if isinstance(s, UniversityMember) :

        print u"s是UniversityMember类或其子类的实例对象"

    else :

    print u"s不是UniversityMember类或其子类的实例对象"

    #执行结果

    E:>python 0319test.txt

    um是UniversityMember类或其子类的实例对象

    s是UniversityMember类或其子类的实例对象

    4.4多重继承

    Python支持多重继承,也就是一个子类可以有多个父类

    多重继承中,子类在没有定义自己的构造方法时,以第一个父类为中心

    如果子类重新定义了自己的构造方法,就不会调用父类的构造方法。但是如果仍然想调用父类的构造方法,可以使用上述提到的两种方法,不过第一种方法只能调用第一父类的构造函数,第二种方法可以自己确定调用哪一个父类的构造方法;如果父类中有同名的方法,通过子类的实例对象去调用的该方法也是第一个父类中的,同样,可以通过父类.父类方法名来确定调用哪一个父类中的方法

    Python多重继承中,其寻找方法的方式有两种

    1. 当类是经典类时,多重继承情况下,会按照深度优先的方式查找。先去自己本身查找,找不到会去第一父类中找,接着去第一父类的父类中找……然后才去第二父类中找,找到就会终止查找,找不到会报错
    2. 当类是新式类(当前类或者其父类继承了object)时,多重继承的情况下,会按照广度优先的方式查找。先去自己本身查找,找不到会去第一父类中找,接着去第二父类的父类中找……然后才去第一父类的父类中找,找到就会终止查找,找不到会报错

    多重继承例子1:

    #coding=utf-8

    class house(object):

        def __init__(self, name):

            print "Calling house constructor"

    class car(object):

        def __init__(self):

            print "Calling car constructor"

    class carHouse(house, car): #多重继承

        pass

    class busHouse(house, car) : #多重继承

        def __init__(self):

            # super(busHouse, self).__init__("sr")

            # 这种方法只能调第一个父类的构造方法

            car.__init__(self)

            #这种方法真正实现随意调用

    c = carHouse("ad")

    b = busHouse()

    #执行结果

    E:>python 0319test.txt

    Calling house constructor

    Calling car constructor

    多重继承例子2:

    class house(object):

        def getHeight(self):

            print u"调用house类的方法"

    class car(object):

        def getHeight(self):

            print u"调用car类的方法"

    class carHouse(house, car): #多重继承

        def __init__(self) :

            pass

        def carHeight(self) :

            # self.getHeight()

            #这种方法默认调的也是第一个父类的方法

            car.getHeight(self) #真正实现了随心所欲的调取想调父类的方法

    c = carHouse()

    c.carHeight()

    #执行结果

    E:>python 0319test.txt

    调用car类的方法

    5、property方法

    通过property方法可以把类对象变量(self.Name)的获取,修改和删除方法自动映射到类变量(d.name)的三种行为

    #coding=utf-8

    import os

    class Dogs(object):

        def __init__(self,name):

            self.Name = name        #注意一定要大写

        def get_dogs_name(self):

            print 'fetch...'

            return self.Name

        def set_dogs_name(self, name):

            print 'change...'

            self.Name = name

        def del_dogs_name(self):

            print 'remove...'

            del self.Name

        name = property(get_dogs_name,set_dogs_name,del_dogs_name,'name

    property docs')

    # name=property(get_dogs_name,set_dogs_name)

    d = Dogs('Tai Di')

    print d.name

    d.name = 'Hashiqi'

    print d.name

    del d.name

    #执行结果

    E:>python 0319test.txt

    fetch...

    Tai Di

    change...

    fetch...

    Hashiqi

    remove...

    #coding=utf-8

    from datetime import datetime

    class Student(object):

        @property

        def birth(self):

            return self._birth

        @birth.setter

        def birth(self, value):

            self._birth = datetime.strptime(value, '%Y-%m-%d')

            print self._birth

        @property

        def age(self):

            currentTime = datetime.now()

            currentDate = currentTime.strftime('%Y-%m-%d')

            timedelta = datetime.strptime(currentDate, '%Y-%m-%d')-self._birth

            return  timedelta.days / 365

    if __name__ == '__main__' :

        s = Student()

        s.birth = '1992-08-18' 

        """用@property修饰的是属性,用@bierh.setter修饰属性的方法,然后后边那个s.birth="XX"会动调用那个方法给birth赋值,然后执行@bierh.setter修

    饰的bierh方法"""

        print u"现在年龄:", s.age

    #执行结果

    E:>python 0319test.txt

    1992-08-18 00:00:00

    现在年龄: 25

    #跟上述代码有相同的结果,对比差异

    #coding=utf-8

    from datetime import datetime

    class Student(object):

        def birth(self, value):

            self._birth = datetime.strptime(value, '%Y-%m-%d')

            print self._birth

        def age(self):

            currentTime = datetime.now()

            currentDate = currentTime.strftime('%Y-%m-%d')

            timedelta = datetime.strptime(currentDate, '%Y-%m-%d')-self._birth

            return  timedelta.days / 365

    if __name__ == '__main__' :

        s = Student()

        s.birth ('1992-08-18') 

        print u"现在的年龄:" ,s.age()

  • 相关阅读:
    c11---位运算相关
    c10---多文件开发
    C9---include,编译
    c8---递归
    c7---函数
    c6----函数的声明和实现
    c5
    Arm 环境上面libgdiplus的简单安装配置
    批量查找可执行文件目录的简单方法
    Android常用工具类
  • 原文地址:https://www.cnblogs.com/pw20180101/p/8932264.html
Copyright © 2011-2022 走看看