Python 入门学习笔记(五)
一、问题引入
Kelly教练每天在训练场忙的焦头烂额,根本没有时间摆弄计算机,需要人帮他处理选手的数据!
运动员在刻苦训练,每跑一个600米,kelly就会计时并将时间记录到计算机中的文本文件中,共有4个选手James、Sarah、Julie和Mikey,分别对应4个文件
james.txt 2-34,3:21,2,34,2.45,3.01,2:01,2:01,3:10,2-22
sarah.txt 2:58,2.58,2:39,2-25,2:55,2:54,2.18,2:55,2:55
julie.txt 2.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-21
mikey.txt 2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38
# 读取文件内容,按逗号进行切分
def get_coach_data(filename):
with open(filename) as f:
line = f.readline()
return line.strip().split(',')
# 输出读取文件的结果
times = get_coach_data('mywork/james.txt')
print('读取文件james.txt后的结果:\n')
print(times)
这里是引用get_coach_data函数的说明
filename为文件路径
f表示文件对象
f.realine()表示读取文件的一行
line.strip().split(’,’)为链式函数写法意思是,先对这一行的数据进行strip(),就是去掉改行头尾空格和换行符。然后对strip()的结果进行split(’,’),对结果以逗号的进行切分形成一个数组。:
# 数据格式标准化
def sanitize(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)
sanitize函数的说明:
time_string为时间数组
splitter是根据原数据的格式来确实分钟和秒的分隔符
(mins,secs) = time_string.split(splitter)以splitter分隔符切分每个时间数据到两个变量中mins,secs
return (mins+’.’+secs)将分钟和秒以字符串点进行连接
# python,一句话搞定数据标准化,排序和去重
james_times = get_coach_data('mywork/james.txt')
print('一句话搞定数据标准化、排序、去重\n')
#set返回的字典中不能包含重复的key,可以用来自动去除重复值
print(sorted(set([sanitize(t) for t in james_times]))[0:3])
这样表示一个选手的信息需要大量的变量,表示多个选手的信息则需要更多的变量,那么有没有一种方法可以简化这种情况。
二、class 类
(1)说明
降低复杂性-》更少的bug-》提高可维护行
类可以将数据与函数绑定在一起,使代码模块化
调用数据和函数,使用对象名.的方式,使代码更加优雅
代码通常称为类的方法,数据通常称为类的属性,实例化的对象称为实例
(2)如何定义类
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定义函数的关键字,其中self是类的实例化
init方法是一个特殊方法会在实例化对象时自动调用,我们会在这个方法中对数据进行赋值。self作为类中函数的第一个参数,方便该方法调用该类的其他属性和方法。
第三部分:自定义的属性和方法
(3)如何使用类
1.创建对象
对象名 = 类名(参数)
2.使用.调用类的方法和属性
对象.属性名
对象.方法名()```python 在这里插入代码片
# 从文件中读取数据
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()))
#OUTPUT
姓名:james,生日:2006-11-11,最快的3次成绩:['2.01', '2.22', '2.34']
(4)类属性
所有对象共享的数据(属性)
定义在类函数声明之后,具体函数定义之前
定义:在 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)
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)
#OUTPUT
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
(5)类方法
所有对象共享的方法
定义:方法定义时,使用@classmethod标记
调用:
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)
@classmethod
def changeAddress(self):
self.address = '中国田径训练基地xx街xx号'
#集训队换地方了
Athlete.changeAddress()
print(julie.address)
print(james.address)
print(Athlete.address)
#OUTPUT
中国足球协会训练基地xx街xx号
中国足球协会训练基地xx街xx号
中国田径训练基地xx街xx号
(6)私有属性和方法
有些时候类中定义的函数并没有将参数传递到类外面,只服务于类,当从外面调用此类函数时,往往不知道该函数的用途,为了防止这种情况的发生,可以将此类函数私有化,拒绝类外访问。
私用的属性和方法的定义:
在属性和方法名前加 __ 两个下划线
如何调用: 只能通过类中的方法来调用私有的属性和方法
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()))
外部调用私有类方法会报错,找不到该属性。
#OUTPUT
---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-23-e9b511a878b8> in <module>
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'