Python面向对象编程
面向对象的世界
代码通常称为类的方法,数据通常称为类的属性,实例化的对象称为实例
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
程序分析:定义运动员类,使得各个具体的运动员的代码有了共同的模板,在实例化的过程中可以使得代码变量更少,有更好的可读性
如何定义类
class Athlete:
第一部分:class定义类的关键字,Athlete符合python标识符命名规则,:表示类内容的开始
def init(self,a_name,a_dob=None,a_times=[]):
第二部分:def定义函数的关键字,init 方法是一个特殊方法会在实例化对象时自动调用,我们会在这个方法中对数据进行赋值。self作为类中函数的第一个参数,方便该方法调用该类的其他属性和方法。
def get_coach_data(filename):
with open(filename) as f:
line = f.readline()
return line.strip().split(',')
# 从文件中读取数据
james_new = get_coach_data('mywork/james_new.txt')
james_name = james_new.pop(0)
james_dob = james_new.pop(0)
james_times = james_new
# 创建Athlete对象
james = Athlete(james_name,james_dob,james_times)
print('姓名:%s,生日:%s,最快的3次成绩:%s' %(james.name,james.dob,james.top3()))
姓名:james,生日:2006-11-11,最快的3次成绩:[‘2.01’, ‘2.22’, ‘2.34’]
如何使用类
1.创建对象
对象名 = 类名(参数)
2.使用.调用类的方法和属性
对象.属性名
对象.方法名()
类属性
所有对象共享的数据
class Athlete:
#运动员集训了,要买东西的同学要把地址改一下
address = '中国足球协会训练基地xx街xx号'
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
julie_new = get_coach_data('mywork/julie_new.txt')
julie_name = julie_new.pop(0)
julie_dob = julie_new.pop(0)
julie_times = julie_new
james_new = get_coach_data('mywork/james_new.txt')
james_name = james_new.pop(0)
james_dob = james_new.pop(0)
james_times = james_new
julie = Athlete(julie_name,julie_dob,julie_times)
james = Athlete(james_name,james_dob,james_times)
print(julie.address)
print(james.address)
print(Athlete.address)
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
如何使用:
定义:
在 init 之上,或者说在类的范围内与方法同等级别,书写变量名=值
调用:
类名.类属性
类方法¶
所有对象共享的方法
class Athlete:
#运动员集训了,要买东西的同学要把地址改一下
address = '中国足球协会训练基地xx街xx号'
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
@classmethod
def changeAddress(self):
self.address = '中国田径训练基地xx街xx号'
#集训队换地方了
Athlete.changeAddress()
print(julie.address)
print(james.address)
print(Athlete.address)
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
中国田径训练基地xx街xx号
如何使用:
定义:
方法定义时,使用@classmethod标记
调用:
类名.类方法
对象.类方法
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name = a_name
self.dob = a_dob
self.times = a_times
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
james = Athlete(james_name,james_dob,james_times)
james.name = 'hehe'
# james.sanitize()
print('姓名:%s,生日:%s,最快的3次成绩:%s' %(james.name,james.dob,james.top3()))
姓名:hehe,生日:2006-11-11,最快的3次成绩:[‘2.01’, ‘2.22’, ‘2.34’]
sanitize()函数,直接调用的话,不知道有什么用呢?
sanitize()函数是在Athlete中,专门用来处理将训练的时间进行标准化的,干脆把它声明为私用的,不会用的话干脆让你看不到就行了。
james.name = 'hehe’你不可以这样啊,怎么可以直接改呢! 干脆不让你改
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.__name = a_name
self.dob = a_dob
self.times = a_times
def sayName(self):
print(self.__name)
def top3(self):
return sorted(set([self.__sanitize(t) for t in self.times]))[0:3]
def __sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
james = Athlete(james_name,james_dob,james_times)
# print(james._name)
# james.__sanitize()
print('姓名:%s,生日:%s,最快的3次成绩:%s' %(james.name,james.dob,james.top3()))
AttributeError Traceback (most recent call last)
in
2 # print(james._name)
3 # james.__sanitize()
----> 4 print(‘姓名:%s,生日:%s,最快的3次成绩:%s’ %(james.name,james.dob,james.top3()))
AttributeError: ‘Athlete’ object has no attribute ‘name’
私用的属性和方法的定义:
在属性和方法名前加 __ 两个下划线
练习
第一题(30分)
数据如下:
stu1.txt 孙同学,2020-5-21,20,‘男’,77,56,77,76,92,58,-91,84,69,-91
stu2.txt 赵同学,2020-11-3,24,‘女’,65,68,72,95,-81,71,86,91,57,91
stu3.txt 王同学,2021-8-7,25,‘男’,87,78,90,-76,88,47,100,65,69,100
stu4.txt 李同学,2021-8-10,29,‘男’,92,54,85,71,-91,68,77,68,95,95
以上四个txt文档在work路径下可以找到。
定义Student类,包括name、dob、age、gender和score属性,包括top3方法用来返回学生的最大的3个成绩(可重复)、sanitize方法用来将负的分数变为正的分数,负的分数可能是输入错误。声明stu_list对象组数用于存储所有的学生对象。最后输出所有的学生信息包括姓名、生日、年龄、性别、最高的3个分数。
第一题的输出结果如下,供参考:
# 请在此处完成代码
def get_data(filename):
with open(filename) as fr:
line = fr.readline()
return line.strip().split(',')
class Student:
def __init__(self,a_name,a_dob,a_age,a_gender,a_score=[]):
self.name = a_name
self.dob = a_dob
self.age = a_age
self.gender = a_gender
self.score = a_score
def sanitize(self,score_string):
score_string = int(score_string)
if score_string < 0:
score_string = abs(score_string)
return score_string
def top3(self):
return sorted([self.sanitize(t) for t in self.score],reverse=True)[0:3]
stu_list = [0 for i in range(4)]
filename = ['./work/stu1.txt','./work/stu2.txt','./work/stu3.txt','./work/stu4.txt']
for i in range(4):
data = get_data(filename[i])
#print(data)
name = data.pop(0)
dob = data.pop(0)
age = data.pop(0)
gender = data.pop(0)
score = data
stu_list[i] = Student(name,dob,age,gender,score)
print('姓名:%s 生日:%s 年龄:%s 性别:%s 分数:%s'
%(stu_list[i].name,stu_list[i].dob,stu_list[i].age,stu_list[i].gender,stu_list[i].top3()))
姓名:孙同学 生日:2020-5-21 年龄:20 性别:‘男’ 分数:[92, 91, 91]
姓名:赵同学 生日:2020-11-3 年龄:24 性别:‘女’ 分数:[95, 91, 91]
姓名:王同学 生日:2021-8-7 年龄:25 性别:‘男’ 分数:[100, 100, 90]
姓名:李同学 生日:2021-8-10 年龄:29 性别:‘男’ 分数:[95, 95, 92]
第二题(30分)
数据格式如下:
stu5.txt 特长同学,2020-10-5,20,‘男’,180,87,98,77,76,92,58,-76,84,69,-47
stu6.txt 特长同学,2020-10-6,20,‘女’,230,76,48,82,88,92,58,-91,84,69,-68
以上两个txt文档在work路径下可以找到。
定义Spostudent、Artstudent为Student的子类,在子类的属性里面新增了spe为特长分数。Spostudent包括的top3方法返回的是最低的3个得分(可重复),Artstudent包括top3方法返回的是最高的3个得分(可重复),最后使用多态的方式输出2个特长同学的姓名、生日、年龄、性别、分数、特长分。
第二题的输出结果如下,供参考:
# 请在此处完成代码
class Spostudent(Student):
def __init__(self,a_name,a_dob,a_age,a_gender,a_spe,a_score=[]):
Student.__init__(self,a_name,a_dob,a_age,a_gender,a_score)
self.spe = a_spe
def top3(self):
return sorted([self.sanitize(t) for t in self.score])[0:3]
class Artstudent(Student):
def __init__(self,a_name,a_dob,a_age,a_gender,a_spe,a_score=[]):
Student.__init__(self,a_name,a_dob,a_age,a_gender,a_score)
self.spe = a_spe
def top3(self):
return sorted([self.sanitize(t) for t in self.score],reverse=True)[0:3]
def print_stu_info(student):
print('姓名:%s 生日:%s 年龄:%s 性别:%s 分数:%s 特长分:%s'
%(student.name,student.dob,student.age,student.gender,student.top3(),student.spe))
stu5 = get_data('./work/stu5.txt')
spostu = Spostudent(stu5.pop(0),stu5.pop(0),stu5.pop(0),stu5.pop(0),stu5.pop(0),stu5)
stu6 = get_data('./work/stu6.txt')
artstu = Artstudent(stu6.pop(0),stu6.pop(0),stu6.pop(0),stu6.pop(0),stu6.pop(0),stu6)
print_stu_info(spostu)
print_stu_info(artstu)
姓名:特长同学 生日:2020-10-5 年龄:20 性别:‘男’ 分数:[56, 58, 69] 特长分:180
姓名:特长同学 生日:2020-10-6 年龄:20 性别:‘女’ 分数:[92, 91, 91] 特长分:230