类与对象练习
1、面向对象三大特性,各有什么用处,说说你的理解。
答案:
封装:明确区分内外,控制外部对隐藏属性的操作行为,隔离复杂度。
隐藏实现细节,使代码模块化
多态:多种形态。好处:1、增加程序的灵活性(以不变应万变,不论对象千变万化,同一种方式调用。)
2、增加了程序的可扩展性
一个基类派生出多个子类,子类在继承了方法名的同时,又对父类的方法做出了不同的实现
接口的重用(同一种接口,多种实现)
继承:子类继承父类的特性,但同时又可以拥有自己独特的属性。解决代码重用问题。
扩展已存在的代码
2、类的属性和对象的属性有什么区别?
类的属性分为函数属性与数据属性:数据属性是对所有对象共享的,函数属性是与对象绑定的。 对象的属性是实例化,可能来自于类定义,也可能依据实例化后定义的。
3、面向过程编程与面向对象编程的区别与应用场景?
面向过程编程:好处是复杂问题流程化,简洁化。缺点是可扩展性差。适用于实现后很少改动的程序,或者是一次行的程序。 面向对象编程:好处是可扩展性高,缺点是复杂度远高于面向过程。适用于需求多变的任务中,例如游戏,用户层等。
4、类和对象在内存中是如何保存的。
类是在定义阶段便生成命名空间,以字典形式保存。通过__dict__查看 对象以字典形式保存。
5、什么是绑定到对象的方法、绑定到类的方法、解除绑定的函数、如何定义,如何调用,给谁用?有什么特性?
(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"]
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中经典类和新式类的区别
多继承中,首先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', '存储过程的名字')
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)
报错 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()
__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()
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()
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 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()
G D A B F C B D A
15、 请编写一段符合多态特性的代码.
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.建立业务领域概念之间的关系
方法:
从用例中找名词
领域建模的三字经方法:找名词、加属性、连关系。
参考:http: // www.cnblogs.com / linhaifeng / articles / 6182264.# html # _label15
http: // www.cnblogs.com / linhaifeng / articles / 7341318.# html
17、 请写一个小游戏,人狗大站,2个角色,人和狗,游戏开始后,生成2个人,3条狗,互相混战,
人被狗咬了会掉血,狗被人打了也掉血,狗和人的攻击力,具备的功能都不一样。注意,请按题14领域建模的方式来设计类。
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、编写程序, 在元类中控制把自定义类的数据属性都变成大写.
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、编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
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方法
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序列化保存到文件里,并在下一次重启程序时能
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()

浙公网安备 33010602011771号