类与对象练习
1、面向对象三大特性,各有什么用处,说说你的理解。
1 2 3 4 5 6 7 8 9 | 答案: 封装:明确区分内外,控制外部对隐藏属性的操作行为,隔离复杂度。 隐藏实现细节,使代码模块化 多态:多种形态。好处: 1 、增加程序的灵活性(以不变应万变,不论对象千变万化,同一种方式调用。) 2 、增加了程序的可扩展性 一个基类派生出多个子类,子类在继承了方法名的同时,又对父类的方法做出了不同的实现 接口的重用(同一种接口,多种实现) 继承:子类继承父类的特性,但同时又可以拥有自己独特的属性。解决代码重用问题。 扩展已存在的代码 |
2、类的属性和对象的属性有什么区别?
1 2 | 类的属性分为函数属性与数据属性:数据属性是对所有对象共享的,函数属性是与对象绑定的。 对象的属性是实例化,可能来自于类定义,也可能依据实例化后定义的。 |
3、面向过程编程与面向对象编程的区别与应用场景?
1 2 | 面向过程编程:好处是复杂问题流程化,简洁化。缺点是可扩展性差。适用于实现后很少改动的程序,或者是一次行的程序。 面向对象编程:好处是可扩展性高,缺点是复杂度远高于面向过程。适用于需求多变的任务中,例如游戏,用户层等。 |
4、类和对象在内存中是如何保存的。
1 2 | 类是在定义阶段便生成命名空间,以字典形式保存。通过__dict__查看 对象以字典形式保存。 |
5、什么是绑定到对象的方法、绑定到类的方法、解除绑定的函数、如何定义,如何调用,给谁用?有什么特性?
1 2 3 4 5 6 | ( 1 )绑定到对象的方法:在类中定义没有加装饰器修饰的方法。 对象.bound_method() 自动将对象当做第一个参数传入 ( 2 )绑定到类的方法:在类中定义的装饰器@ classmethod 修饰的方法。 类.bound_method() 自动将类当第一个参数传入 ( 3 )非绑定方法:在类中用@ staticmethod 装饰器装饰的方法。 没有自动传值,不绑定类和对象,类和对象均可调用。 |
6、使用实例进行获取、设置、删除数据, 分别会触发类的什么私有方法。
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(): def __init__( self ,msg): self .key = msg def __getitem__( self , item): return self .__dict__.get(item) def __setitem__( self , key, value): self .__dict__[key] = value def __delitem__( self , key): del self .__dict__[key] a = A( "name" ) print (a.__dict__) a[ "key" ] print (a.key) a[ "key" ] = "val" print (a.__dict__) # print(a.key) del a[ "key" ] print (a.__dict__) |
7、python中经典类和新式类的区别
1 2 3 4 | 多继承中,首先 object 是所有python类的基类,它提供了一些常见方法(如__str__)的实现。 在python2中,没有显式继承 object 类的类,以及该类的子类都是经典类。 python2中,显式地声明继承 object 类,以及该类的子类都是新式类。 新式类是广度优先,python3中都是新式类,根据mro列表中的顺序 |
8、如下示例, 请用面向对象的形式优化以下代码
def exc1(host, port, db, charset, sql):
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', '存储过程的名字')
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Exc( object ): def __init__( self ,host,port,db,charset = "utf-8" ): self .host = host self .port = port self .db = db self .charset = charset self .conn = connect( self .host, self .port, self .db, self .charset) def exc1( self ,sql): return self .conn.execute(sql) def exc1( self ,sql): return self .conn.call_proc(sql) obj = Exc( '127.0.0.1' , 3306 , 'db1' ) obj.exc1( 'select * from tb1;' ) obj.exc2( '存储过程的名字' ) |
9、示例1, 现有如下代码, 会输出什么:
class People(object):
__name = "luffy"
__age = 18
p1 = People()
print(p1.__name, p1.__age)
1 2 | 报错 print (p1._People__name,p1._People__age) |
10、示例2, 现有如下代码, 会输出什么:
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(类方法), 并分别补充代码执行下列方法。
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 | a.foo( 10 ) a.class_foo( 23 ) A.static_foo( 12 ) a.static_foo( 23 ) |
12、请执行以下代码,解释错误原因,并修正错误。
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 | d.eat |
13、 下面这段代码的输出结果将是什么?请解释。
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 4 | 答案: 1 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址 1 2 1 更改Child1,Child1的x指向了新的内存地址 3 2 3 更改Parent,Parent的x指向了新的内存地址 |
14、多重继承的执行顺序,请解答以下输出结果是什么?并解释。
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()
1 2 3 4 5 6 7 8 9 10 | 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 | class People( object ): def talk( self ): print ( "Lalalalala......" ) class Dog( object ): def talk( self ): print ( "woof" ) class Cat( object ): def talk( self ): print ( "mew" ) def func(animal): animal.talk() p = People() d = Dog() c = Cat() func(p) func(d) func(c) |
16、 很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?
原因就是因为你还没掌握一门面向对象设计利器,即领域建模,请解释下什么是领域建模,以及如何通过其设计面向对象的程序?
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 | class People( object ): def __init__( self ,name,hp = 100 ,hit = 50 ): self .name = name self .hit = hit self .hp = hp def attack( self ,obj): obj.hp = obj.hp - self .hit class Dog( object ): def __init__( self ,name,hp = 80 ,hit = 30 ): self .name = name self .hit = hit self .hp = hp def bite( self ,obj): obj.hp = obj.hp - self .hit p1 = People( "alex" ) p2 = People( "jack" ) d1 = Dog( "1" ) d2 = Dog( "2" ) d3 = Dog( "3" ) d1.bite(p1) p2.attack(d2) print (p1.__dict__) print (d2.__dict__) |
18、编写程序, 在元类中控制把自定义类的数据属性都变成大写.
1 2 3 4 5 | class Mymeta( type ): def __init__( self ,class_name,class_bases,class_dic): for i in class_dic: if super (Mymeta, self ).__init__(class_name,class_bases,class_dic) |
19、编写程序, 在元类中控制自定义的类无需init方法
20、编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Student(): __count = 0 def __init__( self ,name,age): self .name = name self .age = age Student.__count + = 1 @staticmethod def total(): print ( "共有学生%s名" % Student.__count) return # @property std1.info def info( self ): print ( "student:%s,age:%s" % ( self .name, self .age)) std1 = Student( "alex" , 19 ) std2 = Student( "Jack" , 20 ) Student.total() std1.info() |
21、编写程序, A继承了B, 俩个类都实现了handle方法, 在A中的handle方法中调用B的handle方法
1 2 3 4 5 6 7 8 9 | class B(): def handle( self ): print ( "B" ) class A(B): def handle( self ): # print("A") super (A, self ).handle() a = A() a.handle() |
22、编写程序, 如下有三点要求:
a、自定义用户信息数据结构, 写入文件, 然后读取出内容, 利用json模块进行数据的序列化和反序列化
e.g
{
"egon": {"password": "123", 'status': False, 'timeout': 0},
"alex": {"password": "456", 'status': False, 'timeout': 0},
}
b、定义用户类,定义方法db,例如执行obj.db可以拿到用户数据结构
c、在该类中实现登录、退出方法, 登录成功将状态(status)修改为True, 退出将状态修改为False(退出要判断是否处于登录状态).
密码输入错误三次将设置锁定时间(下次登录如果和当前时间比较大于10秒即不允许登录)用面向对象的形式编写一个老师角色,
并实现以下功能, 获取老师列表, 创建老师、删除老师、创建成功之后通过pickle序列化保存到文件里,并在下一次重启程序时能
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 | import json,time class User(): def __init__( self ,name,password): self .name = name self .password = password self .status = False self .timeout = 0 def db( self ): f = open ( "习题5.json" , "r" ,encoding = "utf-8" ) data = json.load(f) return data def save( self ): obj = {} obj[ self .name] = { "password" : self .password, "status" : self .status, "timeout" : self .timeout} f = open ( "习题5.json" , "w" ,encoding = "utf-8" ) json.dump(obj,f) def login( self ): f = open ( "习题5.json" , "r+" ,encoding = "utf-8" ) 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.truncate( 0 ) json.dump(data,f) print ( "Welcome......" ) break else : data[ self .name][ "status" ] = True f.truncate( 0 ) json.dump(data, f) print ( "Welcome......" ) break else : data[ self .name][ "status" ] = time.time() f.truncate( 0 ) json.dump(data, f) def exit( self ): f = open ( "习题5.json" , "r+" , encoding = "utf-8" ) data = json.load(f) if data[ self .name][ "status" ] = = True : data[ self .name][ "status" ] = = False f.truncate( 0 ) json.dump(data, f) else : print ( "退出状态" ) user1 = User( "alex" , "123" ) user1.save() user1.exit() user1.login() |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步