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')