Python面向对象编程

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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淬子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值