python 要掌握面向对象,你得会做这些题
1,面向对象三大特性,各有什么用处,说说你的理解。
1 2 3 4 5 | 继承:解决代码重用问题 多态:多态性,可以在不考虑对象类型的情况下而直接使用对象 封装:明确的区分内外,控制外部对隐藏属性的操作行为,隔离复杂度 |
2,类的属性和对象的属性有什么区别?
1 2 3 | 类的属性:数据属性和函数属性,数据属性是所有对象共有的,函数属性是绑定对象使用的 对象的属性:对象是类的实例化 |
3,面向过程编程与面向对象编程的区别与应用场景?
1 2 3 4 5 | 面向过程:复杂的问题流程化,简单化 应用场景:不再需要扩展了,监测脚本,自动部署脚本,软件解压安装 面向对象:特征与技能的结合体 一切皆对象 应用场景:用户需求经常变化,互联网应用,游戏,企业内部应用 |
4,类和对象在内存中是如何保存的。
1 | 类和对象的属性:以字典的形式保存的 |
5,什么是绑定到对象的方法、绑定到类的方法、解除绑定的函数、如何定义,如何调用,给谁用?有什么特性
1 2 3 4 5 6 | 绑定到对象的方法:就应该由对象来调用, 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,使用实例进行 获取、设置、删除 数据, 分别会触发类的什么私有方法
1 2 3 4 5 6 7 8 | class A( object ): pass a = A() a[ "key" ] = "val" a = a[ "key" ] del a[ "key" ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 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中经典类和新式类的区别
1 2 3 | 经典类:py2 没有继承 object 的类,以及它的子类都称之为经典类 - - > 深度优先 新式类:py3 继承 object 的类,以及它的子类都称之为新式类 - - >广度优先 |
8,如下示例, 请用面向对象的形式优化以下代码
1 2 3 4 5 6 7 8 9 10 11 12 | 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, 现有如下代码, 会输出什么:
1 2 3 4 5 6 | class People( object ): __name = "luffy" __age = 18 p1 = People() print (p1.__name, p1.__age) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class People( object ): __name = "luffy" __age = 18 p1 = 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__': <attribute '__dict__' of 'People' objects>, # '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None} print (p1._People__name,p1._People__age) # luffy 18 |
10,示例2, 现有如下代码, 会输出什么:
1 2 3 4 5 6 7 8 9 10 | class People( object ): def __init__( self ): print ( "__init__" ) def __new__( cls , * args, * * kwargs): print ( "__new__" ) return object .__new__( cls , * args, * * kwargs) People() |
1 2 | # 结果:__new__ # __init__ |
11,请简单解释Python中 staticmethod(静态方法)和 classmethod(类方法), 并分别补充代码执行下列方法。
静态方法:非绑定方法,类和对象都可以调用
类方法:绑定给类的方法啊,类调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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(<class '__main__.A'>, alice) executing static_foo(alice) executing static_foo(alice) ''' |
12,请执行以下代码,解释错误原因,并修正错误。
错误原因:@property可以将函数属性转化为数据属性
1 2 3 4 5 6 7 8 9 10 11 | 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() |
报错内容:
1 2 3 4 | Traceback (most recent call last): File "D:/py.py" , line 27 , in <module> d.eat() TypeError: 'NoneType' object is not callable |
改正如下:
1 2 3 4 5 6 7 8 9 10 11 | 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,下面这段代码的输出结果将是什么?请解释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址 # 1 2 1 更改Child1,Child1的x指向了新的内存地址 # 3 2 3 更改Parent,Parent的x指向了新的内存地址 |
14,多重继承的执行顺序,请解答以下输出结果是什么?并解释。
1 2 3 4 5 | super ()表示的是 子类的mro()列表中的下一个 print (G.mro()) [< class '__main__.G' >, < class '__main__.D' >, < class '__main__.A' >, < class '__main__.B' >, < class 'object' >] print (F.mro()) [< class '__main__.F' >, < class '__main__.C' >, < class '__main__.B' >, < class '__main__.D' >, < class '__main__.A' >, < class 'object' >] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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,请编写一段符合多态特性的代码.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Animal: def __init__( self , name): self .name = name class 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 talking wang is talking ''' |
16,很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?原因就是因为你还没掌握一门面向对象设计利器,即领域建模,请解释下什么是领域建模,以及如何通过其设计面向对象的程序?http://www.cnblogs.com/alex3714/articles/5188179.html 此blog最后面有详解
1 2 3 4 5 6 7 8 9 10 11 | 领域模型,顾名思义,就是需求所涉及的领域的一个建模,更通俗的讲法是业务模型。 定义: 需求到面向对象的桥梁 作用: 1. 发掘重要的业务领域概念 2. 建立业务领域概念之间的关系 方法: 从用例中找名词 领域建模的三字经方法:找名词、加属性、连关系。 参考:http: / / www.cnblogs.com / linhaifeng / articles / 6182264.html #_label15 http: / / www.cnblogs.com / linhaifeng / articles / 7341318.html |
17,请写一个小游戏,人狗大站,2个角色,人和狗,游戏开始后,生成2个人,3条狗,互相混战,人被狗咬了会掉血,狗被人打了也掉血,狗和人的攻击力,具备的功能都不一样。注意,请按题14领域建模的方式来设计类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 .aggressivity class 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,编写程序, 在元类中控制把自定义类的数据属性都变成大写.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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': <function Chinese.walk at 0x0000000001E7B950>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None} ''' |
19,编写程序, 在元类中控制自定义的类无需init方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 obj class 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,编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 2 3 4 5 6 7 8 9 | # 结果: # 1 # {'name': 'james', 'sex': 'male', 'age': 32} # 2 # {'name': 'enbede', 'sex': 'male', 'age': 23} # 2 # {'__module__': '__main__', '_count': 2, '__init__': <function Student.__init__ at 0x00000190B1B959D8>, 'learn': <property object at 0x00000190B19047C8>, 'tell_count': <staticmethod object at 0x00000190B1B9CAC8>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None} # 总共实例化了:2 # james is learning |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # _*_ 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__': <function Student.__init__ at 0x000001E5DA9759D8>, 'learn': <function Student.learn at 0x000001E5DA975A60>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None} # # Process finished with exit code 0 |
21,编写程序, A 继承了 B, 俩个类都实现了 handle 方法, 在 A 中的 handle 方法中调用 B 的 handle 方法
1 2 3 4 5 6 7 8 9 10 | 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秒即不允许登录)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import json import time class 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 序列化保存到文件里,并在下一次重启程序时能读取到创建的老师, 例如程序目录结构如下.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | . | - - 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题, 它们雷同的功能, 是否可以通过继承的方式进行一些优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 伪代码 class Behavior( object ): def fetch( self , keyword): 通过 keyword 参数 查询出对应的数据列表 class School(Behavior): pass class Teacher(Behavior): pass s = School() t = Teacher() s.fetch( "school" ) t.fetch( "teacher" ) |
28:编写一个学生类,产生一堆学生对象
要求:有一个计数器(属性),统计总共实例了多少个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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则判定为死亡。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 .aggresivity class Garen(Hero): pass class Riven(Hero): pass g1 = Garen( '草丛论' , 100 , 20 ) r1 = Riven( '放逐之刃' , 80 , 50 ) print (r1.life_value) g1.attack(r1) print (r1.life_value) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构