• Title


    一、静态属性

    class Room:
        tag=1
        def __init__(self,name,owner,width,length,heigh):
            self.name=name
            self.owner=owner
            self.width=width
            self.length=length
            self.heigh=heigh
    
        @property
        def cal_area(self):
            # print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
            return  self.width * self.length
    r1=Room('厕所','alex',100,100,100000)
    print(r1.cal_area)

      要点:@property + return 把公共函数变成数据属性,实例调用的调用的时候去掉小括号,像调用普通属性一样调用它。

    二、类方法

    class Room:
        tag=1
        def __init__(self,name,owner,width,length,heigh):
            self.name=name
            self.owner=owner
            self.width=width
            self.length=length
            self.heigh=heigh
    
        @classmethod
        def tell_info(cls,x):
            print(cls)
            print('-->',cls.tag,x)
    
    r1=Room('厕所','alex',100,100,100000)
    Room.tell_info(10)
    
    #输出:
    <class '__main__.Room'>
    --> 1 10

       要点:@classmethod 和 cls  专门供类使用的方法,类调用的时候不用传实例,也可以被实例调用(不建议这么做,本来就是划给类的方法,你还去调用它,四不是四傻) 

    三、静态方法

      是一种普通函数,位于类定义的命名空间中,不会对任何实例类型进行操作,python为我们内置了函数staticmethod来把类中的函数定义成静态方法。

      应用场景:编写类时需要采用很多不同的方式来创建实例,而我们只有一个__init__函数,此时静态方法就派上用场了。

    class Room:
        tag=1
        def __init__(self,name,owner,width,length,heigh):
            self.name=name
            self.owner=owner
            self.width=width
            self.length=length
            self.heigh=heigh
    
        @staticmethod
        def wash_body(a,b,c):
            print('%s %s %s正在洗澡' %(a,b,c))
    
    Room.wash_body('alex','yuanhao','wupeiqi')
    print(Room.__dict__)
    r1=Room('厕所','alex',100,100,100000)
    print(r1.__dict__)
    r1.wash_body('alex','yuanhao','wupeiqi')
    
    #输出:
    alex yuanhao wupeiqi正在洗澡
    { 'wash_body': <staticmethod object at 0x000000000261B438>, ..... }
    {'name': '厕所', 'owner': 'alex', 'width': 100, 'length': 100, 'heigh': 100000}
    alex yuanhao wupeiqi正在洗澡

     

    class Date:
        def __init__(self,year,month,day):
            self.year=year
            self.month=month
            self.day=day
        @staticmethod
        def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间
            t=time.localtime() #获取结构化的时间格式
            return Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回
        @staticmethod
        def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间
            t=time.localtime(time.time()+86400)
            return Date(t.tm_year,t.tm_mon,t.tm_mday)
    
    a=Date('1987',11,27) #自己定义时间
    b=Date.now() #采用当前时间
    c=Date.tomorrow() #采用明天的时间
    
    print(a.year,a.month,a.day)
    print(b.year,b.month,b.day)
    print(c.year,c.month,c.day)

     要点:@staticmethod  只是名义上归属类管理,不能调用类变量、实例变量,只是类的工具包。

    四、组合

      组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。

      用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系。

      当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。 

    class Trunk:
        pass
    
    class Head:
        pass
    
    class Person:
        def __init__(self,id_num,name):
            self.id_num=id_num
            self.name=name
            self.trunk=Trunk()
            self.head=Head()
    p1=Person('111111','alex')
    print(p1.name)
    print(p1.id_num)
    print(p1.__dict__)
    
    #输出:
    alex
    111111
    {'id_num': '111111', 'name': 'alex', 'trunk': <__main__.Trunk object at 0x000000000290B358>, 'head': <__main__.Head object at 0x000000000290B390>}

      

    class School:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def zhao_sheng(self):
            print('%s 正在招生' %self.name)
    
    class Course:
        def __init__(self,name,price,period,school):
            self.name=name
            self.price=price
            self.period=period
            self.school=school
    
    s1=School('oldboy','北京')
    s2=School('oldboy','南京')
    s3=School('oldboy','东京')
    
    c1=Course('linux',10,'1h','oldboy 北京')
    c2=Course('linux',10,'1h',s1)

      要点:把s1当做参数传进去,可以不写死。

    五、继承

      继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类。

    class Grandfather:
        pass
    
    class Father(Grandfather): #单继承 Father是派生类,grandfather 是基类
        pass
    
    class son(Father,Grandfather): #多继承
        pass

      继承使用产生的场景:如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时我们不可能从头开始写一个类B,这就用到了类的继承的概念。通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用。

          除了继承与派生的概念还有一个概念是需要提出的那就是:组合。组合就是指在一个类中以另外一个类的对象作为数据属性,成为类的组合。

          组合与继承两者到底什么的关系?1.继承的方式:通过继承建立了派生类与基类的关系,两者之间是“是”的关系。当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师    2.组合的方式:用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程(当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

    class School:
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def zhao_sheng(self):
            print('%s 正在招生' %self.name)
    
    class Course:
        def __init__(self,name,price,period,school):
            self.name=name
            self.price=price
            self.period=period
            self.school=school
    
    s1=School('北大','北京') 
    
    c1=Course('linux',10,'1h',s1)
    print(c1.name) #linux
    print(c1.school) # <__main__.School object at 0x02182330>
    print(c1.school.name) # 北大
    print(c1.school.addr) # 北京
    举例

      在这个例子中呢,创建了两个类,一个是学校类一个是课程类。需要将课程类与学校类进行相关联的时候,继承在这里是不合适的,那我们采用组合的方式来对这两个类进行关联,这样就在实例化一门课程的时候把学校的信息进行关联。

      子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

    class Dad:
        '这个是爸爸类'
        money=10
        def __init__(self,name):
            print('爸爸')
            self.name=name
        def hit_son(self):
            print('%s 正在打儿子' %self.name)
    
    class Son(Dad):
        money = 1000000000009
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def hit_son(self):
            print('来自儿子类')
    举例

      

      接口继承(抽象类):

      从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。

      抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

      抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计 。

    import abc
    class All_file(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def read(self):
            pass
    
        @abc.abstractmethod
        def write(self):
            pass
    
    class Disk(All_file):
        def read(self):
            print('disk read')
    
        def write(self):
            print('disk write')
    
    class Cdrom(All_file):
        def read(self):
            print('cdrom read')
    
        def write(self):
            print('cdrom write')
    
    
    class Mem(All_file):
        def read(self):
            print('mem read')
    
        def write(self):
            print('mem write')
    
    m1=Mem()
    m1.read()
    m1.write()
    接口继承例子

      父类规定子类中必须实现的方法,但父类不实现(基类接口进行规范化子类)。

      

      顺序继承:

    class A:
        # def test(self):
        #     print('A')
        pass
    class B(A):
        # def test(self):
        #     print('B')
    
        pass
    class C(A):
        def test(self):
            print('C')
        # pass
    
    class D(B):
        # def test(self):
        #     print('D')
        pass
    
    class E(C):
        def test(self):
            print('E')
        # pass
    
    class F(D,E):
        # def test(self):
        #     print('F')
        pass
    f1=F()
    f1.test()   #经典类:F->D->B->A-->E-->
    
    print(F.__mro__)
    
    #F-->D->B-->E--->C--->A新式类
    
    #输出:
    E
    (<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    顺序继承例子

      继承的顺序:A为父类

      新式类找的顺序:

       在子类中调用父类的方法super():

    class Vehicle1:
        Country='China'
        def __init__(self,name,speed,load,power):
            self.name=name
            self.speed=speed
            self.load=load
            self.power=power
        def run(self):
            print('开动啦')
            print('开动啦')
    class Subway(Vehicle1):
            def __init__(self,name,speed,load,power,line):
               # Vehicle.__init__(self,name,speed,load,power)
               super().__init__(name,speed,load,power)  #super(__class__,self).__init__(name,speed,load,power)
               self.line=line
            def show_info(self):
                print(self.name,self.speed,self.load,self.power,self.line)
            def run(self):
                # Vehicle.run(self)
                super().run()
                print('%s %s 线,开动啦' %(self.name,self.line))
    line13=Subway('北京地铁','10km/s',1000000000,'',13)
    line13.show_info()
    line13.run()
    print(line13.__class__)
    在子类中调用父类的例子

      当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)。

    学习资料来源:海峰老师

  • 相关阅读:
    Constraint.constant动画效果
    poj3469 Dual Core CPU --- 最小割
    开发Blog整理
    Android 四大组件学习之BroadcastReceiver四
    在光标处插入指定文本(支持文本域和文本框)
    图片显示插件
    Extjs4 自定义组件
    Windows英文版GitHub客户端使用操作流程图文攻略教程现没中文版
    innerHTML和innerText怎么区分
    button和input type=button的区别及注意事项
  • 原文地址:https://www.cnblogs.com/guotianbao/p/6918126.html
Copyright © 2020-2023  润新知