继承、派生、新式类与经典类

目录

  • 继承

    • 1.什么是继承?
    • 2.为什么要继承?
    • 3.如何实现继承?
    • 寻找继承关系
    • 继承背景下对象属性的查找顺序
  • 派生
    • 什么是派生?
    • 子类派生出新的属性,并重用父类的属性
  • 新式类与经典类
    • 钻石继承(菱形继承)
    • 通过继承实现修改json模块数据类型

继承

Downwards is the only way forwards .——《盗梦空间》

面向对象阶段最重要的知识点:继承、封装、多态

1.什么是继承?

指新建类的方法,新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或者超类。
继承特征:
子类可以继承父类的属性(特征与技能),并且可以派生出自己的属性(特征与技能)。
在python中一个子类可以继承多个父类,其他语言一个子类只可以继承一个父类

2.为什么要继承?

继承的目的是为了减少代码的冗余(减少重复代码)

3.如何实现继承?

1.首先要确定好谁是子类谁是父类.
2.在定义类时子类+(),()内写父类,实现继承.

class 父类:
     pass

class 子类(父类):
     pass
#父类
class ParentClass1:
    pass

class ParentClass2:
    pass
#子类
class Subclass1(ParentClass1):
    pass

class Subclass2(ParentClass1,ParentClass2):
    pass

print(Subclass2.__bases__)
#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
#查看继承的父类:__bases__,是类的属性,用来查找自己的父类,通过元组的形式返回所继承的父类

寻找继承关系

如何寻找继承关系?
要想寻找继承关系,首先抽象再继承。
——先抽象(抽象思想):

奥巴马——》人类——》动物类
麦兜——》猪类——》动物类
小丁丁——》狗类——》动物类
抽象定义动物类,父类。
特征:眼睛、鼻子...
技能:
吃喝...

——再继承(在程序中)

继承的关系:
对象:特征与技能的结合体
类:一系列特征与技能的结合体
继承:一系列类相同的特征与技能的结合体

class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Students(SchoolPeople):
    def choose_course(self):
        print(f'{self.name} is choosing course.')

class Teachers(SchoolPeople):
    def teach(self):
        print(f'{self.name} is teaching students.')

stu1 = Students('xiaoming','15','男')
stu1.choose_course()

xiaoming is choosing course.

继承背景下对象属性的查找顺序

对象查找属性先从自己的名称空间查找,若当前类是子类,并且没有该属性,就去父类中查找,如果父类也没有就报错__class__查看当前对象的类。
注意:对象查找属性不管父类有没有这个属性,只要子类有就不会去父类中查找

查看对象名称空间
print(tea1.__dict__)
查看对象的属性,查看当前对象的类__class__

查看子类名称空间
print(tea1.__class__.__dict__)
查看父类名称空间
print(tea1.__class__.__bases__[0].__dict__)#查看第一个父类的名称空间

#验证对象属性的查找顺序
class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.f1()

class Soo(Foo):
    def f1(self):
        print('Soo.f1')

soo_obj = Soo()
soo_obj.f2()
'''
Foo.f2
Soo.f1
'''

派生

什么是派生?

派生指子类继承父类的属性,并且派生自己的属性。
如果子类和父类都有这个属性,以子类自己的属性为准。
继承指的是类与类的关系,子类与父类是从属关系。

子类派生出新的属性,并重用父类的属性

class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Teacher(SchoolPeople):
    def __init__(self,name,age,gender,level,sal):
        SchoolPeople.__init__(self,name,age,gender)#重用父类的属性
        self.level = level#派生出的属性
        self.sal = sal#派生出的属性

tech1 = Teacher('xiaohua','17','男','10','5w')
print(tech1.level)

重用父类属性的两种方式

方式一:

直接通过父类.(调用)__init__,把__init__当做普通函数使用,传入对象与继承的属性,如上例中的重用。
方式二:

super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,通过“.”
指向父类的名称空间。

class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Teacher(SchoolPeople):
    def __init__(self,name,age,gender,level,sal):
        super().__init__(name,age,gender)#重用父类的属性(注意括号里面没有self)
        self.level = level#派生出的属性
        self.sal = sal#派生出的属性

注意:两种方式不要混着使用

新式类与经典类

新式类与经典类(了解)(面试会问)

在python2中才有经典类,没有继承object的类都是经典类。

python3中都是新式类,继承object类的都是新式类,py3中默认继承object类。

钻石继承(菱形继承)

关于mro()

mro():是object——》type的函数,用来查看多继承情况下,当前类的继承顺序, .mro()方法其实就是在查找mro()方法
一个子类如果继承多个父类,属性的查找顺序是从左向右依次查找,最后找object

钻石继承

钻石继承(菱形继承):钻石继承就是一个子类有多个父类,每个父类又有多个不同的父类......这些父类的祖先最终是同一个祖宗。(面试问)

在多继承情况下可能会出现钻石继承的情况。

钻石继承下对象属性的查找顺序

--经典类——》深度优先:从左向右查找,一条分支找到底,若果没找到就去另一条分支继续找。

——新式类——》广度优先:从左向右查找,和经典类的区别是最后找所有分支共同的父类

验证查找顺序代码

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

通过继承实现修改json模块数据类型

通过继承实现为json增加数据类型:

import json
from datetime import date ,datetime
print(json.JSONDecoder)#<class 'json.decoder.JSONDecoder'>
print(datetime.today())#当前时间
print(date.today())#当前日期
#从开发者的角度考虑,可以将json不支持的数据类型转成json支持的是数据类型
#如:
'''dict1 = {
    'name':'tank',
    'today':str(datetime.today()),
    'today1':str(date.today())
}
res = json.dumps(dict1)
print(res)
#{"name": "tank", "today": "2019-10-10 14:30:26.967368", "today1": "2019-10-10"}
从开源者的角度考虑,Python time strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间,
        格式由参数format决定。'''
class MyJson(json.JSONEncoder):
    def default(self,o):
        if isinstance(o,datetime):#判断o是否是datetime的一个实例对象
            return o.strftime('%Y-%m-%d %X')

        elif isinstance(o,date):
            return o.strftime('%Y-%m-%d')
        else:
            return super().default(self,o)#在json中也有default这个方法

dict1 = {
    'name':'tank',
    'today':datetime.today(),
    'today1':date.today()
}
res = json.dumps(dict1,cls = MyJson)#cls=None,默认指向的是原json的JSONEncoder,加上之后优先使用外面的类
print(res)

原文地址:https://www.cnblogs.com/ghylpb/p/11648032.html

时间: 2024-11-13 11:39:08

继承、派生、新式类与经典类的相关文章

python之继承、抽象类、新式类和经典类

一.上节补充1.静态属性静态属性 : 类的属性,所有的对象共享这个变量 如果用对象名去修改类的静态属性:在对象的空间中又创建了一个属性,而不能修改类中属性的值 操作静态属性应该用类名来操作 例1:请你写一个类,能够统计一共实例化了多少个对象? class Foo: count = 0 def __init__(self): Foo.count += 1 f1 = Foo() print(f1.count) # 1 f2 = Foo() f3 = Foo() f4 = Foo() f5 = Foo

Python新式类与经典类的区别

1.新式类与经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类,则称之为“经典类”. “新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”. 官方文档 https://www.python.org/doc/new

python中新式类和经典类的区别

1).python在类中的定义在py2-3版本上是使用的有新式类和经典类两种情况,在新式类和经典类的定义中最主要的区别是在定义类的时候是否出现引用object;如:经典类:Class 类名::而新式类定义的时候使用Class 类名(object): 2).定义来源:在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类,则称之为“经典类”. 3).衍生:“新式类”和“经典

新式类 VS 经典类

一.概述 Python中支持多继承,也就是一个子类可以继承多个父类/基类.当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类 和 经典类的区别. 二.多继承 1 class Food(object): 2 3 def __init__(self, name, color): 4 self.name = name 5 self.color = color 6 7 def eatable(self): 8 print("%s

新式类与经典类的比较

新式类与经典类的区别: 首先: Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,不必显式的继承object 即:新式类都从object继承,经典类不需要 其次: ------新式类对象可以直接通过__class__属性获取自身类型:type ------继承搜索的顺序发生了改变 经典类多继承属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧 -- 即 经典类深度优先 新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动    

Python新式类和经典类的区别

@Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x2 = NewStyleClass() print x1.__class__, type(x1) print x2.__class__, type(x2) 输出结果: __main__.ClassicClass <type 'instance'> <class '__main__.NewSt

python 新式类和经典类(了解)

在python2中,有新式类和经典类和经典类的区别: 新式类 继承自object或object的子类,这样的类就叫新式类. class A(object): pass print(A.__bases__) 结果: (<class 'object'>,) 经典类 没有继承object或object的子类. >>> class A: ... pass ... >>> A.__bases__ () >>> 而在python3中不再有这种区别,所有

03-python的新式类和经典类区别

新式类就是  class person(object): 这种形式的, 从py2.2 开始出现的 新式类添加了: __name__ is the attribute's name. __doc__ is the attribute's docstring. __get__(object) is a method that retrieves the attribute value from object. __set__(object, value) sets the attribute on

python中的__new__与__init__,新式类和经典类(2.x)

在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1. 新式类对象可以直接通过__class__属性获取自身类型:type 2. 继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动 例子: 经典类: 搜索顺序是(D,B,A,C)>>&