类的继承 --- 练习

1、下面这段代码的输出结果将是什么?请解释。

class Parent(object):
  	x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)

'''
解答:
继承背景下对象属性的查找顺序:
1.对象查找属性会先从对象的名称空间中查找
2.若对象没有,则会去类里面找
3.若当前类是子类,并且没有对象找的属性,回去父类中查找
注:对象查找属性,若子类有,不管父类有没有,都以子类为准。

print(Parent.x,Child1.x,Child2.x) # 1 1 1
解释:对象查找属性会先从对象所在的名称空间查找,定义的类Parest的名称空间中有x=1,所以在查找的时候,会直接查找到Parent名称空间中的x=1,所以Parent.x输出为1。而Child1的名称空间中没有x,所以会在所继承的父类中寻找,即输出为Child.x=1。Child2的原理通Child1所示,输出Child2.x为1.

Child1.x=2
print(Parent.x,Child.x,Child.x) # 1 2 1
解释:对象查找属性会先从对象所在的名称空间查找,定义的类Parent的名称空间中有x=1,所以在查找的时候,会直接查找到Parent名称空间中的x=1,所以Parent.x输出为1。对象Child1中有x=2,并按找子类中的x=2为准,所以Child1.x输出为2。而Child2中没有x,只能去父类中寻找,所以Child.x输出为1.

Parent.x=3
print(Parent.x,Child1.x,Child2.x) # 3 2 3
解释:Parent.x=3,将类Parent中的x=1替换成了x=3,此时的Parent.x输出为3,而之间已经在Child1中添加了x=2,所以Child1输出为2,但是Child2中没有x,所以只能继承父类Parent中的x,故,Child.x输出为3
'''

2、多重继承的执行顺序,请解答以下输出结果是什么?并解释。

        class A(object):
		   def __init__(self):
		       print('A')
		       super(A, self).__init__()

		class B(object):
		   def __init__(self):
		       print('B')
		       super(B, self).__init__()

		class C(A):
		   def __init__(self):
		       print('C')
		       super(C, self).__init__()

		class D(A):
		   def __init__(self):
		       print('D')
		       super(D, self).__init__()

		class E(B, C):
		   def __init__(self):
		       print('E')
		       super(E, self).__init__()

		class F(C, B, D):
		   def __init__(self):
		       print('F')
		       super(F, self).__init__()

		class G(D, B):
		   def __init__(self):
		       print('G')
		       super(G, self).__init__()

		if __name__ == '__main__':
		   g = G()
		   f = F()
	
	

'''
解答:
super() 的作为子类来调用的时候会产生一个特殊的对象,通过“.”指向父类的名称空间
g = G() 的顺序是G-->D-->A-->B 先调用类G(),然后打印'G',此时再调用super的时候会指向父的名称空间,依次按照顺序来进行指向,之后指向D内,再按照同样的原理,从D指向A,在A内调用super的时候,指向的是object,因为python3内的类默认都是新式类,在会按照新式类的继承顺序执行,当遇到object的时候就停止进行向下一步的寻找,然后再调用下一个父类,再调用父类B的时候,原理也是一样的。

f = F() 的顺序是F-->C-->B-->D-->A 这个的原理与上一个原理式一样的,但是需要注意的是,当有两个父类都指向A的时候,会选择最后一条指向。这就是为什么C之后没有指向A,而是D之后指向A的原因。
'''

3、什么是新式类,什么是经典类,二者有什么区别?什么是深度优先,什么是广度优先?
'''
解答:
新式类:继承object的类就是新式类,在python3中默认是新式类。
广度优先:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问依次

经典类:没有继承object的类就是经典类,在python2中凡是没有object的类都是经典类。
深度优先:从上往下对每一层一次访问,在每一层中,从左到右访问节点,访问完一层就进入下一层,直到没有节点访问为止。
'''

4、用面向对象的形式编写一个老师类, 老师有特征:编号、姓名、性别、年龄、等级、工资,老师类中有功能。

1.生成老师唯一编号的功能,可以用hashlib对当前时间加上老师的所有信息进行校验得到一个hash值来作为老师的编号   
	def create_id(self):
	   pass
2.获取老师所有信息
	def tell_info(self):
	   pass

3.将老师对象序列化保存到文件里,文件名即老师的编号,提示功能如下
	def save(self):
		with open('老师的编号','wb') as f:
			pickle.dump(self,f)

4.从文件夹中取出存储老师对象的文件,然后反序列化出老师对象,提示功能如下
	def get_obj_by_id(self,id):
		return pickle.load(open(id,'rb'))

5、按照定义老师的方式,再定义一个学生类

6、抽象老师类与学生类得到父类,用继承的方式减少代码冗余

1.生成老师唯一编号的功能,可以用hashlib对当前时间加上老师的所有信息进行校验得到一个hash值来作为老师的编号

import hashlib
import pickle

class Teacher:

    def __init__(self,name,sex,age,grade,wage):
        self.name = name
        self.sex = sex
        self.age = age
        self.grade = grade
        self.wage = wage

    def create_id(self):
        S1 = self.name+self.sex+self.age+self.grade+self.wage
        m = hashlib.md5()
        m.update(S1.encode('utf8'))
        self.id = m.hexdigest()

2.获取老师所有信息
def tell_info(self):
    print(self.id,self.name,self.sex,self.age,self.grade,self.wage)

3.将老师对象序列化保存到文件里,文件名即老师的编号,提示功能如下 
def save(self):
    with open(f'{self.id}','wb') as f:
        pickle.dump(self, f)
        
4.从文件夹中取出存储老师对象的文件,然后反序列化出老师对象,提示功能如下
def get_obj_by_id(self,id):
    with open(id,'rb') as frb:
        return pickle.load(frb)

5、按照定义老师的方式,再定义一个学生类

import hashlib
import datetime
import pickle

class Student:
    def __init__(self, name, sex, age, course ):
        self.name = name
        self.sex = sex
        self.age = age
        self.course = course
        
    def create_id(self):
        time_now = datetime.datetime.now()
        time_str = time_now.strftime('%Y-%m-%d %X')
        counts = time_str + self.name + self.sex + str(self.age) + str(self.course) 
        m = hashlib.md5()
        m.update(counts.encod('utf-8'))
        self.id = m.hexdigest()

    def tell_info(self):
        print(self.id, self.name, self.sex, self.age, self.course)

    def save(self):
        with open(f'{self.id}', 'wb') as fwb:
            pickle.dump(self, fwb)

    def get_obj_by_id(self, id):
        with open(id, 'rb')as frb:
            return pickle.load(frb)


6、抽象老师类与学生类得到父类,用继承的方式减少代码冗余

import hashlib
import datetime
import pickle

class Parent:
    def __init__(self, , name, sex, age)
        self.name = name
        self.sex = sex
        self.age = age
        self.id = self.create_id()
        
    def create_id(self):
        time_now = datetime.datetime.now()
        time_str = time_now.strftime('%Y-%m-%d %X')
        counts = time_str + self.name + self.sex + str(self.age) + str(self.level) + str(self.salary)
        m = hashlib.md5()
        m.update(counts.encod('utf-8'))
        id = m.hexdigest()
        return id

    def tell_info(self):
        print(self.__dict__)

    def save(self):
        with open(f'{self.id}', 'wb') as fwb:
            pickle.dump(self, fwb)

    def get_obj_by_id(self, id):
        with open(id, 'rb')as frb:
            return pickle.load(frb)


class Teacher(Parent):
    def __init__(self, name, sex, age, level, salary, ):
        super().__init__(name, sex, age)
        self.level = level
        self.salary = salary

    def tell_info(self):
        print(super().tell_info(), self.level, self.salary)


class Student(Parent):
    def __init__(self, name, sex, age, course):
        super().__init__(name, sex, age)
        self.course = course

    def tell_info(self):
        print(super().tell_info(), self.course)
        
teac1 = Teacher('nick','男',18,10,30000)
stu1 = Student('hsw','男',18,'python') 

posted @ 2019-10-10 21:10  余人。  阅读(301)  评论(0编辑  收藏  举报