1,面向对象三大特性,各有什么用处,说说你的理解。
继承:解决代码重用问题多态:多态性,可以在不考虑对象类型的情况下而直接使用对象封装:明确的区分内外,控制外部对隐藏属性的操作行为,隔离复杂度
2,类的属性和对象的属性有什么区别?
类的属性:数据属性和函数属性,数据属性是所有对象共有的,函数属性是绑定对象使用的对象的属性:对象是类的实例化
3,面向过程编程与面向对象编程的区别与应用场景?
面向过程:复杂的问题流程化,简单化应用场景:不再需要扩展了,监测脚本,自动部署脚本,软件解压安装面向对象:特征与技能的结合体 一切皆对象应用场景:用户需求经常变化,互联网应用,游戏,企业内部应用
4,类和对象在内存中是如何保存的。
类和对象的属性:以字典的形式保存的
5,什么是绑定到对象的方法、绑定到类的方法、解除绑定的函数、如何定义,如何调用,给谁用?有什么特性
绑定到对象的方法:就应该由对象来调用,def tell_info(self):...obj.tell_info()绑定到类的方法:就应该由类来调用,@classmethod def from_conf(cls):... class.from_conf()非绑定方法:不与类或对象绑定,谁都可以调用,@staticmethod def create_id():... obj.create_if()/class.create_id()
6,使用实例进行 获取、设置、删除 数据, 分别会触发类的什么私有方法
class A(object): pass a = A() a["key"] = "val" a = a["key"] del a["key"]
# class A(object):# def __setitem__(self, key, value):# self.__dict__[key] = value## def __getitem__(self, item):# # return self.__dict__[item]# return self.__dict__.get(item)## def __delitem__(self, key):# del self.__dict__[key]## a = A()# a["key"] = "val"# print(a.__dict__)# # a = a["key"]# # print(a)# del a["key"]# print(a.__dict__)
7,python中经典类和新式类的区别
经典类:py2 没有继承object的类,以及它的子类都称之为经典类 --> 深度优先新式类:py3 继承object的类,以及它的子类都称之为新式类 -->广度优先
8,如下示例, 请用面向对象的形式优化以下代码
1、在没有学习类这个概念时,数据与功能是分离的 def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx # 每次调用都需要重复传入一堆参数 exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
9,示例1, 现有如下代码, 会输出什么:
class People(object): __name = "luffy" __age = 18 p1 = People() print(p1.__name, p1.__age)
class People(object): __name = "luffy" __age = 18p1 = People()# print(p1.__name, p1.__age)# 报错:AttributeError: 'People' object has no attribute '__name'print(p1.__dict__) #{}print(People.__dict__)# {'__module__': '__main__', '_People__name': 'luffy', # '_People__age': 18, '__dict__':, # '__weakref__': , '__doc__': None}print(p1._People__name,p1._People__age) # luffy 18
10,示例2, 现有如下代码, 会输出什么:
class People(object): def __init__(self): print("__init__") def __new__(cls, *args, **kwargs): print("__new__") return object.__new__(cls, *args, **kwargs)People()
# 结果:__new__# __init__
11,请简单解释Python中 staticmethod(静态方法)和 classmethod(类方法), 并分别补充代码执行下列方法。
静态方法:非绑定方法,类和对象都可以调用
类方法:绑定给类的方法啊,类调用
class A(object): def foo(self, x): print("executing foo(%s, %s)" % (self,x)) @classmethod def class_foo(cls, x): print("executing class_foo(%s, %s)" % (cls,x)) @staticmethod def static_foo(x): print("executing static_foo(%s)" % (x))a = A()
class A(object): def __init__(self,name): self.name=name def foo(self, x): print("executing foo(%s, %s)" % (self,x)) @classmethod def class_foo(cls, x): print("executing class_foo(%s, %s)" % (cls,x)) @staticmethod def static_foo(x): print("executing static_foo(%s)" % (x))# a = A('alice')# a.foo('alice')# A.class_foo('alice')# a.static_foo('alice')# A.static_foo('alice')'''executing foo(<__main__.A object at 0x000002A5FED12AC8>, alice)executing class_foo(, alice)executing static_foo(alice)executing static_foo(alice)'''
12,请执行以下代码,解释错误原因,并修正错误。
错误原因:@property可以将函数属性转化为数据属性
class Dog(object): def __init__(self,name): self.name = name @property def eat(self): print(" %s is eating" %self.name)d = Dog("ChenRonghua")d.eat()
报错内容:
Traceback (most recent call last): File "D:/py.py", line 27, ind.eat()TypeError: 'NoneType' object is not callable
改正如下:
class Dog(object): def __init__(self,name): self.name = name @property def eat(self): print(" %s is eating" %self.name)d = Dog("ChenRonghua")d.eat
因为有了property,用户就可以直接输入得到结果,对于使用者来说,感知不到其属性,这就是使用property的方便之处,此方法必须有一个返回值。return 或者print都可以。
为什么要用property?
一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
13,下面这段代码的输出结果将是什么?请解释。
class Parent(object): x = 1class Child1(Parent): passclass Child2(Parent): passprint(Parent.x, Child1.x, Child2.x)Child1.x = 2print(Parent.x, Child1.x, Child2.x)Parent.x = 3print(Parent.x, Child1.x, Child2.x)# 1 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址# 1 2 1 更改Child1,Child1的x指向了新的内存地址# 3 2 3 更改Parent,Parent的x指向了新的内存地址
14,多重继承的执行顺序,请解答以下输出结果是什么?并解释。
super()表示的是 子类的mro()列表中的下一个 print(G.mro()) [, , , , ] print(F.mro()) [ , , , , , ]
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()# G# D# A# B## F# C# B# D# A
15,请编写一段符合多态特性的代码.
class Animal: def __init__(self, name): self.name = nameclass People(Animal): def talk(self): print('%s is talking' % self.name)class Dog(Animal): def talk(self): print('%s is talking' % self.name)def func(animal): animal.talk()# p=People('alice')# d=Dog('wang')# func(p)# func(d)'''alice is talkingwang is talking'''
16,很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?原因就是因为你还没掌握一门面向对象设计利器,即领域建模,请解释下什么是领域建模,以及如何通过其设计面向对象的程序? 此blog最后面有详解
领域模型,顾名思义,就是需求所涉及的领域的一个建模,更通俗的讲法是业务模型。 定义: 需求到面向对象的桥梁 作用: 1.发掘重要的业务领域概念 2.建立业务领域概念之间的关系 方法: 从用例中找名词 领域建模的三字经方法:找名词、加属性、连关系。 参考:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label15 http://www.cnblogs.com/linhaifeng/articles/7341318.html
17,请写一个小游戏,人狗大站,2个角色,人和狗,游戏开始后,生成2个人,3条狗,互相混战,人被狗咬了会掉血,狗被人打了也掉血,狗和人的攻击力,具备的功能都不一样。注意,请按题14领域建模的方式来设计类。
class Animal: def __init__(self, name,life_value,aggressivity): self.name = name self.life_value = life_value self.aggressivity = aggressivity def attack(self,enemy): enemy.life_value -= self.aggressivityclass People(Animal): camp='home' def attack(self,enemy): super().attack(enemy) print('from people')class Dog(Animal): camp='wo' def attack(self,enemy): super().attack(enemy) print('from dog')p1=People('alice',80,30)p1=People('alex',80,30)d1=Dog('w1',90,50)d2=Dog('w2',90,50)d3=Dog('w3',90,50)# print(p1.life_value)# d1.attack(p1)# print(p1.life_value)# print(d1.life_value)# p1.attack(d1)# print(d1.life_value)
18,编写程序, 在元类中控制把自定义类的数据属性都变成大写.
class Mymetaclass(type): def __new__(cls,name,bases,attrs): update_attrs={} for k,v in attrs.items(): if not callable(v) and not k.startswith('__'): update_attrs[k.upper()]=v else: update_attrs[k]=v return type.__new__(cls,name,bases,update_attrs) class Chinese(metaclass=Mymetaclass): country='China' tag='Legend of the Dragon' #龙的传人 def walk(self): print('%s is walking' %self.name) print(Chinese.__dict__)'''{'__module__': '__main__', 'COUNTRY': 'China', 'TAG': 'Legend of the Dragon', 'walk':, '__dict__': , '__weakref__': , '__doc__': None}'''
19,编写程序, 在元类中控制自定义的类无需init方法.
class Mymeta(type): def __new__(cls,class_name,class_bases,class_dic): update_dic = {} for i in class_dic: if not callable(class_dic[i]) and not i.startswith('__'): update_dic[i.upper()]=class_dic[i] else: update_dic[i]=class_dic[i] return type.__new__(cls,class_name,class_bases,update_dic) def __call__(self, *args, **kwargs): obj=object.__new__(self) if args: raise TypeError('must be keyword argument') for i in kwargs: obj.__dict__[i]=kwargs[i] return objclass Chinese(metaclass=Mymeta): country='china' tag='legend of the dragon' def talk(self): print('%s is talking'%self.name)# print(Chinese.__dict__)# ch=Chinese(name='alice',age=18)# ch.talk()# print(ch.__dict__)
20,编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
class Student: __count = 0 def __init__(self, name, age): self.name = name self.age = age Student.__count += 1 @property def talk(self): print('%s is talking' % self.name) @staticmethod def tell_count(): print('总共实例化了 %s 人' % Student.__count)# s1 = Student('alice', 18)# s2 = Student('alex', 20)# s3 = Student('egon', 28)# Student.tell_count()# s1.tell_count()# s1.talk# s2.talk
结果:
# 结果:# 1# {'name': 'james', 'sex': 'male', 'age': 32}# 2# {'name': 'enbede', 'sex': 'male', 'age': 23}# 2# {'__module__': '__main__', '_count': 2, '__init__':, 'learn': , 'tell_count': , '__dict__': , '__weakref__': , '__doc__': None}# 总共实例化了:2# james is learning
# _*_ coding: utf-8 _*_'''练习1:编写一个学生类,产生一堆学生对象, (5分钟)要求:有一个计数器(属性),统计总共实例了多少个对象'''class Student: count = 0 def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age Student.count +=1 def learn(self): print("%s is learning"%self.name)stu1 = Student('james','male',32)print(stu1.count)print(stu1.__dict__)stu2 = Student('enbede','male',23)print(stu2.count)print(stu2.__dict__)print(Student.count)print(Student.__dict__)# 结果:# 1# {'name': 'james', 'sex': 'male', 'age': 32}# 2# {'name': 'enbede', 'sex': 'male', 'age': 23}# 2# {'__module__': '__main__', 'count': 2, '__init__':, 'learn': , '__dict__': , '__weakref__': , '__doc__': None}# # Process finished with exit code 0
21,编写程序, A 继承了 B, 俩个类都实现了 handle 方法, 在 A 中的 handle 方法中调用 B 的 handle 方法
class B: def handle(self): print('from B handle')class A(B): def handle(self): super().handle() # print('from A handle')# a=A()# a.handle()
22,编写程序, 如下有三点要求:
- 自定义用户信息数据结构, 写入文件, 然后读取出内容, 利用json模块进行数据的序列化和反序列化
- 定义用户类,定义方法db,例如 执行obj.db可以拿到用户数据结构
- 在该类中实现登录、退出方法, 登录成功将状态(status)修改为True, 退出将状态修改为False(退出要判断是否处于登录状态).密码输入错误三次将设置锁定时间(下次登录如果和当前时间比较大于10秒即不允许登录)
import jsonimport timeclass User: def __init__(self, name, password): self.name = name self.password = password self.status = False self.timeout = 0 @property def db(self): with open(self.name+'.txt', 'r', encoding='utf-8') as f: data = json.load(f) return data def save(self): obj={} obj[self.name]={'password':self.password,'status':self.status,'timeout':self.timeout} with open(self.name+'.txt', 'w', encoding='utf-8') as f: json.dump(obj,f) def login(self): with open(self.name+'.txt', 'r+', encoding='utf-8') as f: data = json.load(f) count = 0 while count < 3: password = input('password>>:').strip() if password != data[self.name]['password']: count += 1 continue else: if data[self.name]['timeout'] != 0: if time.time() - data[self.name]['timeout'] > 10: print('不允许登录了!超时') break else: data[self.name]['status'] = True f.seek(0) f.truncate() json.dump(data, f) print('----welcome----') break else: data[self.name]['status'] = True f.seek(0) f.truncate() json.dump(data, f) print('----welcome----') break else: data[self.name]['timeout']=time.time() f.seek(0) f.truncate() json.dump(data,f) def quit(self): with open(self.name+'.txt', 'r+', encoding='utf-8') as f: data = json.load(f) if data[self.name]['status'] == True: data[self.name]['status'] = False f.seek(0) f.truncate() json.dump(data, f) else: print('您是退出状态!')# alex=User('alex','123')# egon=User('egon','456')# # alex.save()# # egon.save()# # print(alex.db)# # print(egon.db)# # alex.login()# alex.quit()# # egon.quit()# print(alex.db)# print(egon.db)# alex.login()# egon.login()
23,用面向对象的形式编写一个老师角色, 并实现以下功能, 获取老师列表, 创建老师、删除老师、创建成功之后通过 pickle 序列化保存到文件里,并在下一次重启程序时能读取到创建的老师, 例如程序目录结构如下.
.|-- bin/| |-- main.py 程序运行主体程序(可进行菜单选择等)|-- config/| |-- settings.py 程序配置(例如: 配置存储创建老师的路径相关等)|-- db 数据存储(持久化, 使得每次再重启程序时, 相关数据对应保留)| |-- teachers/ 存储所有老师的文件| |-- ... ...|-- src/ 程序主体模块存放| |-- __init__.py| |-- teacher.py 例如: 实现老师相关功能的文件| |-- group.py 例如: 实现班级相关的功能的文件|-- manage.py 程序启动文件|-- README.md 程序说明文件
24,根据23 题, 再编写一个班级类, 实现以下功能, 创建班级, 删除班级, 获取班级列表、创建成功之后通过 pickle 序列化保存到文件里,并在下一次重启程序时能读取到创建的班级.
25,根据 23题, 编写课程类, 实现以下功能, 创建课程(创建要求如上), 删除课程, 获取课程列表
26,根据23 题, 编写学校类, 实现以下功能, 创建学校, 删除学校, 获取学校列表
27,通过23题, 它们雷同的功能, 是否可以通过继承的方式进行一些优化
伪代码class Behavior(object): def fetch(self, keyword): 通过 keyword 参数 查询出对应的数据列表class School(Behavior): passclass Teacher(Behavior): passs = School()t = Teacher()s.fetch("school")t.fetch("teacher")
28:编写一个学生类,产生一堆学生对象
要求:有一个计数器(属性),统计总共实例了多少个对象
class Studentclass: school = 'jiaotong university' count = 0 def __init__(self,name,age,sex): self.name = name self.age = age self.sex =sex Studentclass.count +=1 def learn(self): print('%s is learning'%self.name)stu1 = Studentclass('james',23,'male')stu2 = Studentclass('poal',24,'male')stu3 = Studentclass('harden',25,'male')print(Studentclass.count)print(stu1.__dict__)print(stu2.__dict__)print(stu3.__dict__)print(stu1.count)print(stu2.count)print(stu3.count)
29:模仿王者荣耀定义两个英雄类
要求:
- 英雄需要有昵称、攻击力、生命值等属性;
- 实例化出两个英雄对象;
- 英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡。
class Hero: def __init__(self,nickname,life_value,aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self,enemy): enemy.life_value -= self.aggresivityclass Garen(Hero): passclass Riven(Hero): passg1=Garen('草丛论',100,20)r1 = Riven('放逐之刃',80,50)print(r1.life_value)g1.attack(r1)print(r1.life_value)