1、OOP的意义, 什么是组合?什么是继承?
参考:https://www.cnblogs.com/zihe/p/7111092.html (讲的非常详细)
Object Oriented Programming 面向对象编程
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程
创建一个组合关系的类:汽车类,包含轮子和方向盘类
class Wheel:
def __init__(self,num,speed):
self.num = num
self.speed = speed
def run(self):
print('Car have %d wheels ,runing in %d speed !'%(self.num,self.speed))
class Steering_wheel:
def __init__(self,angle):
self.angle = angle
def turn(self):
print('Car turn steering wheel ,turning in %d angle !'%self.angle)
class Car:
def __init__(self,price):
self.price = price
car = Car(100)
car.wheel = Wheel(4,20)
car.steering_wheel = Steering_wheel(30)
car.wheel.run()
car.steering_wheel.turn()
class Wheel:
def __init__(self,num,speed):
self.num = num
self.speed = speed
def run(self):
print('Car have %d wheels ,runing in %d speed !'%(self.num,self.speed))
class Steering_wheel:
def __init__(self,angle):
self.angle = angle
def turn(self):
print('Car turn steering wheel ,turning in %d angle !'%self.angle)
class Car:
def __init__(self,num,speed,angle):
self.wheel = Wheel(num,speed)
self.steering_wheel = Steering_wheel(angle)
car = Car(4,30,15)
car.wheel.run()
car.steering_wheel.turn()
创建一个继承关系的类:球员,足球运动员,篮球运动员
class Player :
def __init__(self,name,age):
self.name = name
self.age = age
def run(self):
print(self.name,'running')
class football_player(Player):
def shoot(self):
print(self.name,'shooting')
class basketball_player(Player):
def throw(self):
print(self.name, 'throwing')
Person = basketball_player('Yao ming','30')
Person.throw()
2、举例说明类的类属性和实例属性
参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017594591051072
类内的赋值语句会创建类的属性;类创建的实例可以任意绑定属性为实例属性
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')
s.score = 90
name 为类属性 score为实例属性
3、继承属性搜索是什么?
见python类与对象第5部分,按照继承树,从下到上,从左到右搜索 (新式类为先水平后向上)
4、类的属性和类的方法名称一样可以吗?会出现什么结果?
不可以,调用类的方法的时候会报错
class Wheel:
def __init__(self,num,speed):
self.num = num
self.speed = speed
def num(self):
print('Car have %d wheels ,runing in %d speed !'%(self.num,self.speed))
a = Wheel(4,20)
print(a.num)
a.num()
输出:
4
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/hanshu/test.py", line 10, in <module>
a.num()
TypeError: 'int' object is not callable
5、编程实现:模拟垃圾回收机制,使用引用计数方法,跟踪类有多少个实例被创建
参考:https://www.cnblogs.com/ECJTUACM-873284962/p/8953982.html
对垃圾回收机制和引用计数方法还不是很了解,简单写了一个跟踪类有多少个实例被创建的程序,不一定理解的正确,仅供参考
sum = 0
list =[]
class Node:
def __init__(self,val):
self.val = val
global list
global sum
if val in list:
sum = sum
else:
sum = sum + 1
list.append(val)
n1 = Node('ABC')
n2 = Node('DEF')
n3 = Node('GHI')
n4 = Node('ABC')
n1 = Node('KKK')
print(list)
print(sum)
输出:
['ABC', 'DEF', 'GHI', 'KKK']
4
6、编程实现:定义一个FIFO的队列,需要有push/pop/isEmpty等方法
栈:后进先出(LIFO-last in first out):最后插入的元素最先出来。
队列:先进先出(FIFO-first in first out):最先插入的元素最先出来。
参考:https://blog.csdn.net/klxk3/article/details/75298998 (主要参考对象)
https://www.cnblogs.com/wang-yumin/p/9152812.html
queue = []
def pushQ():
queue.append(input(' enter new string: ').strip()) #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
def deQ():
if len(queue) == 0:
print('cannot pop from an empty queue')
else:
print(queue.pop(0))
def viewQ():
print(queue)
CMDs = {'e': pushQ, 'd': deQ, 'v': viewQ}
def showmenu():
pr = """
(E)nqueue
(D)equeue
(V)iew
(Q)uit
Enter choice:
"""
while True:
while True:
try:
choice = input(pr).strip()[0].lower()
except (EOFError, KeyboardInterrupt, IndexError):
choice = 'q'
print('\nYou picked: [%s]' % choice)
if choice not in 'devq':
print('Invalid option. try again')
else:
break
if choice == 'q':
break
CMDs[choice]()
if __name__ == '__main__':
showmenu()
7、类实例化:第一个调用的方法是什么?
参考:https://blog.csdn.net/qq_34979346/article/details/83744950
https://blog.csdn.net/sj2050/article/details/81172022
__new__是第一个,然后是__init__(如果有的话),__new__用于修改类的特性,__init__用于初始化类的属性
8、编程实现:什么时候调用__init__方法?构造一个带有__init__, __del__方法的类, 并且验证调用的时间,并构造一个加法的方法。
import datetime
class add :
def __init__(self,a,b):
print('init time is :',datetime.datetime.now())
self.a = a
self.b = b
def __del__(self):
print('del time is :',datetime.datetime.now()) #时间输出的用法
print('closed')
def add(self):
print('add time is :',datetime.datetime.now())
self.sum = self.a + self.b
print(self.sum)
return self.sum
a = add(3,5)
print(a.add())
输出:
init time is : 2020-01-01 22:20:22.145262
add time is : 2020-01-01 22:20:22.145262
8
8
del time is : 2020-01-01 22:20:22.147256
closed
9、使用什么语句可以保证文件打开后会被关闭
with/as 和 try/finally 参考13题
10、使用try, except语句中else是如何工作的?简单实现并验证
见 11 题
11、编程练习:编写函数devide(x, y),x为被除数,y为除数。要求考虑异常情况的处理。(提示:被零除,类型不一致等)
参考:https://blog.csdn.net/sunshine__0411/article/details/78536294 (参考写的更准确)
import math
def devide(x,y):
try:
res = x/y
except ZeroDivisionError as e:
return '被除数不能为0'
except TypeError as e:
return '类型异常'
except Exception as e:
return '其他异常'
else:
print('没有异常')
return res
#print(devide(3,0))
print(devide(3,'s'))
12、编程练习:自己定义一个异常类,继承Exception类, 捕获下面的过程:判断 raw_input()输入的字符串长度是否小于5,如果小于5,输出”too short”
class test_input(Exception):
pass
try:
str = input('请输入字符串:')
if len(str) < 5:
raise test_input()
except test_input:
print('too short')
13、使用了finally语句,但是finally语句内部本身就会发生错误,有什么办法避免?
参考:https://blog.csdn.net/bestallen/article/details/51932761?locationNum=10&fps=1
上文提到了一种读取文件发生错误时的处理方法,个人意见尽量减少finally内部的代码的复杂性,或者添加assert
14、使用with语句打开文件,但是出现异常,文件是否可以自动关闭
当程序执行到语句体末尾的时候,将自动关闭文件。出现异常程序中断的时候同样会自动关闭文件。
参考:https://blog.csdn.net/qq_36609501/article/details/87928687
# 打开文件
f = open('test.txt','w+')
try:
# 将数据写入到文件中
f.write('Test')
finally:
# 无论程序是否异常,确保关闭文件
f.close()
with open ('a1.txt','r') as f:
f.readline()
# do_something_else(f)
#到这里时文件已经关闭
15、编程练习:使用断言来验证输入的密码:要求密码必须是数字,字母构成,并且长度大于8
参考:Python 使用正则表达式验证密码必须包含大小写字母和数字 https://www.cnblogs.com/yuanchunli/p/8677866.html
https://segmentfault.com/q/1010000000732038/a-1020000000732447
pwd = input("请输入密码:")
print(pwd)
#isalnum() 方法检测字符串是否由字母和数字组成;
# 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
assert pwd.encode('utf-8').isalnum(), '密码必须由数字或字母组成!'
assert len(pwd) > 8, '密码必须大于8位'