2018-09-07 day 15 类和对象(含作业)

1内置类属性

内置类属性就是魔法属性
魔法属性:属性名的前面和后面都有两个下划线
魔法方法:方法的前后都有两个下划线

lass Person(object):
    '''人类'''
    number = 61
    def __init__(self,name,age,height):
        self.name = name
        self.age = age
        self.height = height

    def run(self):
        print('%s在跑步' % self.name)

    @classmethod
    def count(cls):
        print('人类的数量是%d亿' % cls.number)

    @staticmethod
    def show_number():
        print('人类的数量是%d亿' % Person.number)
'''
if __name__ == '__main__':
    p1 = Person('txf',23,176)
    #1.__name__类的属性  -----> 类的名字(返回值是字符串)
    print(Person.__name__)

    #2.__class__ 属性---->获取对象对应的类,返回值是一个类
    print(Person.__class__)   # 
    print(p1.__class__) # 获取类的引用,相当于类

    #3.__dict__ 属性 ------> 获取对象和类的属性及其对应的值以字典形式返回
    print(Person.__dict__)  # 类的属性
    print(p1.__dict__)  # 对象的属性 {'name': 'txf', 'age': 23, 'height': 176}

    #4.__model__ 类属性------>获取类所在模块的对应的名字
    print(Person.__module__) # __main__

    #5.__bases__ 类的属性---->获取当前类的父类(基类)
    print(Person.__bases__)  # (,)

    #6.__doc__类的属性------>获取类的说明文档
    print(Person.__doc__)  #人类
'''

slots魔法(会导致dict的使用,导致用dict报错)

class Person:
  __slots__ = ('name','age','face') #元组
  pass
'''
限制Person类构造的对象只能有这三个属性,__slots__中村的元素的属性的值来约束当前这个类的对象属性。对象的属性只能比元组中的元素少,不能多。
'''

2.私有化

a.声明:类中的属性和方法都可以通过在属性名和方法名前加两个下划线,变成私有的。
b.特点:只能在当前类中使用
c.原理:在前面有两个下划线的属性名和方法名前添加了'_类名'来阻止外面通过直接访问属性名来使用属性

3.属性的getter和setter

a.保护类型的属性:就是在声明对象属性的时候在属性名前加一个下划线来代表这个属性是受保护的属性。
通过setter来设置值,getter来获取值。
b.添加getter
 @property
def 去掉下划线的属性名(self):
  函数体
  return self.属性名

class Car(object):
    def __init__(self):
        self._color = 'red'
        self._brand = '自行车'

    @property
    def color(self):
        return self._color
'''
使用场景
1.如果想要获取对象的某个属性的值之前,想要在干点儿别的事情(额外的处理)
2.想要拿到某个属性被使用的时刻(比如被调用了几次)
'''
添加:setter
格式:想要有setter必须先有getter
class Car(object):
    def __init__(self):
        self._color = 'red'
        self._brand = '自行车'

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self,color):
        self._color = color


if __name__ == '__main__':
    car = Car()
    print(car.color)
    car.color = 'yellow'
    print(car.color)
'''
red
yellow
'''
总结:私有化(两个下划线,存储的时候会把属性值变成_类+之前的属性名),受保护的(一个下划线,提示此属性受保护)

4.继承

python可以继承,并支持多继承。(让子类直接拥有父类的属性和方法.)

1.继承的语法
class 子类(父类):
    pass
如果没有父类,默认继承object(基类)
'''
2.子类继承父类的所有方法和属性(__slots__的值不会限制,但是子类调用'__dict__'会出错---->父类继承下来的属性获取不到)

5.重写

'''
a.对象的属性是通过继承父类的init方法而继承下来的.

b.如果想保留父类的属性时需要使用super().__init__()

c.1.当子类的方法与父类的方法重名时,就叫重写。
  2.保留父类的方法---->在重写父类方法的时候调用父类的方法-----super().父类的方法

d.类中调用过程:先在当着找----->父类找---->父类的父类------>直到object--->崩溃(依次找)
'''
class Persn(object):
    number = 10
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def info(self):
        print(self.name,self.age)

class Txf(Persn):
    # def __init__(self):
    #    super().__init__() #调用父类的init方法

    def info(self):
        print('重写')

class Ha(Persn):
    def info(self):
        super().info()  #调用父类的info()方法
        print('hahahah')

if __name__ == '__main__':
    txf = Txf('t',12)
    txf.info()

    ha = Ha('x',22)
    ha.info()
'''
重写
x 22
hahahah
'''
练习:Person类name,age必须有参数,sex可以没有。Staff类 要有Person()的属性,但是还要添加salary属性,且创建Staff类的对象的时候只能传入name参数。
class Person(object):
    def __init__(self,name,age,sex = 'boy'):
        self.name = name
        self.age = age
        self.sex = sex

class Staff(Person):
    def __init__(self,name,salary = '10k'):
        super().__init__(name,23)
        self.salary = salary

if __name__ == '__main__':
    p1 = Person('txf',12)
    staff = Staff('name')
    print(staff.name)

6.运算符的重载

'''
定义:如果希望类的对象支持相应的运算符操作(如:+,-,*....)就必须实现相应的魔法方法。
'''
class Student(object):

    def __init__(self,name,age,score):
        self.name = name
        self.age = age
        self.score = score

    #重写加方法
    #self:加号前面的对象  other:加号后面的对象
    def __add__(self,other):
        return self.score + other.score

    #重写大于方法
    #注意:重载>和<可以只重载一个,另一个比较的时候会比较自动取反
    def __gt__(self, other):
        if self.score > other.score:
            return '%s年纪大' % self.name
        return  '%s年纪大' % other.name


if __name__ == '__main__':

    stu1 = Student('txf',23,99)
    stu2 = Student('xf',21,12)
    print(stu1 + stu2)
'''
111
txf年纪大
False
'''
总结:一般情况下需要对>或者<进行重载,重载后可以通过sort()直接对对象的列表进行排序
'''
重写__str__
'''
    def __str__(self):
        return str(self.__dict__)

作业

0.定义一个学生类。有属性:姓名、年龄、成绩(语文,数学,英语)[每课成绩的类型为整数]
方法: a. 获取学生的姓名:getname() b. 获取学生的年龄:getage()
c. 返回3门科目中最高的分数。get_course()

class Student(object):
    def __init__(self,name,age,score= []):
        self.name = name
        self.age = age
        self.score = score

    def getname(self):
        return self.name

    def getage(self):
        return self.age

    def max_score(self):
        return max(self.score)

if __name__ == '__main__':
    stu1 = Student('txf',23,[65,99,55])
    print(stu1.getage())
    print(stu1.getage())
    print(stu1.max_score())
'''
23
23
99
'''

1.建立一个汽车类Auto,包括轮胎个数,汽车颜色,车身重量,速度等成员变量,并通过不同的构造方法创建实例。至少要求 汽车能够加速 减速 停车。 再定义一个小汽车类CarAuto 继承Auto 并添加空调、CD等成员变量 覆盖加速 减速的方法

class Auto(object):
    def __init__(self,tyre = 4,color = 'red',weight = '100kg',speed = 24):
        self.tyre = tyre
        self.color = color
        self.weight =weight
        self.speed = speed

    def up_speed(self,up_speed):
        print('加速%d,速度变为%dkm/h' % (up_speed,self.speed+up_speed))
        # return self.speed + up_speed

    def down_speed(self,down_speed):
        self.speed -= down_speed
        if self.speed <= 0:
            Auto.stop(self)
        else:
            print('减速%d,速度变为%dkm/h' % (down_speed, self.speed))
            # return self.speed

    def stop(self):
        self.speed = 0
        print('停车了')
        # return self.speed

class CarAuto(Auto):
    def __init__(self,conditioner = True,CD = True):
        super().__init__()
        self.conditioner = conditioner
        self.CD = CD

    def up_speed(self, up_speed):
        print('加速%d,速度变为%dkm/h' % (up_speed, self.speed + up_speed))
        # return self.speed + up_speed

    def down_speed(self, down_speed):
        self.speed -= down_speed
        if self.speed <= 0:
            Auto.stop(self)
        else:
            print('减速%d,速度变为%dkm/h' % (down_speed, self.speed + down_speed))
            # return self.speed

    def stop(self):
        self.speed = 0
        print('停车了')
        # return self.speed


auto = CarAuto()
auto.down_speed(12)
auto.up_speed(23)
auto.stop()
print('空调:%s CD:%s' % (auto.conditioner,auto.CD))
'''
减速12,速度变为24km/h
加速23,速度变为35km/h
停车了
空调:True CD:True
'''

2.创建一个名为User 的类,其中包含属性firstname 和lastname ,还有用户简介通常会存储的其他几个属性。在类User 中定义一个名 为describeuser() 的方法,它打印用户信息摘要;再定义一个名为greetuser() 的方法,它向用户发出个性化的问候。

管理员是一种特殊的用户。编写一个名为Admin 的类,让它继承User类。添加一个名为privileges 的属性,用于存储一个由字符串(如"can add post"、"can delete post"、"can ban user"等)组成的列表。编写一个名为show_privileges()的方法,它显示管理员的权限。创建一个Admin 实例,并调用这个方法。

class User(object):
    def __init__(self,firstname,lastname,sex = '男',hobby = '女'):
        self.firstname = firstname
        self.lastname = lastname
        self.sex = sex
        self.hobby = hobby

    def describeuser(self):
        print('姓名:%s 性别:%s 爱好:%s' % (self.lastname + self.firstname,self.sex,self.hobby))

    @staticmethod
    def greetuser():
        print('早上好,单身狗')

class Admin(User):
    def __init__(self,firstname,lastname,privileges = ['can add post',"can delete post","can ban user"]):
        super().__init__(firstname,lastname)
        self.privileges = privileges

    def show_privileges(self):
        for x in self.privileges:
            print(x,end= ' ')


user = User('xf','t')
user.describeuser()
User.greetuser()

admin = Admin('xf','t',['can fly'])
admin.show_privileges()

'''
姓名:txf 性别:男 爱好:女
早上好,单身狗
can fly 
'''

3.创建一个Person类,添加一个类字段用来统计Perosn类的对象的个数

class Person(object):
    count = 0
    def __init__(self):
        Person.count += 1


p1 = Person()
p2 = Person()
p3 = Person()
print(Person.count)

(尝试)5.写一个类,其功能是:1.解析指定的歌词文件的内容 2.按时间显示歌词 提示:歌词文件的内容一般是按下面的格式进行存储的。歌词前面对应的是时间,在对应的时间点可以显示对应的歌词

[00:00.20]蓝莲花
[00:00.80]没有什么能够阻挡
[00:06.53]你对自由地向往
[00:11.59]天马行空的生涯
[00:16.53]你的心了无牵挂
[02:11.27][01:50.22][00:21.95]穿过幽暗地岁月
[02:16.51][01:55.46][00:26.83]也曾感到彷徨
[02:21.81][02:00.60][00:32.30]当你低头地瞬间
[02:26.79][02:05.72][00:37.16]才发觉脚下的路
[02:32.17][00:42.69]心中那自由地世界
[02:37.20][00:47.58]如此的清澈高远
[02:42.32][00:52.72]盛开着永不凋零
[02:47.83][00:57.47]蓝莲花

class lyric_save(object):
    def __init__(self,time,word):
        self.time = time
        self.word = word

    def __gt__(self, other):
        return self.time > other.time

    def __str__(self):
        return '%.2f %s' % (self.time,self.word)

class Lyric_resove(object):
    def __init__(self,song_name):
        self.song_name = song_name
        self.lyric_list = []
        self.collect()
    def collect(self):
        try:
            with open('./%s.txt' % self.song_name,'r',encoding='utf-8') as f:
                line = f.readline()
                while line:
                    self.test(line)
                    line = f.readline()
                self.lyric_list.sort(reverse=True)
        except FileNotFoundError:
            print('文件不存在')


    def test(self,content):
        contents = content.split(']')
        word = contents[-1]
        for  times in contents[:-1]:
            time = float(times.lstrip('[')[0:2])*60 + float(times.lstrip('[')[3:])
            ly_save = lyric_save(time,word)
            self.lyric_list.append(ly_save)


    def print_lyric(self,user_input):
        for x in self.lyric_list:
            if x.time <= user_input:
                return x.word


ly = Lyric_resove('蓝莲花')
print(ly.print_lyric(10))

(选做)6.使用面向对象做一个游戏(打飞机和坦克,以及自己设计一个都行)

你可能感兴趣的:(2018-09-07 day 15 类和对象(含作业))