美文网首页
python基础 03

python基础 03

作者: 一诺千金_5079 | 来源:发表于2018-03-17 15:14 被阅读0次

    面向对象

    一般步骤

    Step 1. 定义类
    类是对象的蓝图和模板 有了类就可以创建对象
    定义类需要做两件事:数据抽象和行为抽象
    数据抽象 - 抽取对象共同的静态特征(找名词)- 属性
    行为抽象 - 抽取对象共同的动态特征(找动词)- 方法
    定义类的关键字 - class - 类名(每个单词首字母大写)
    Step 2. 调用构造方法创建学生对象
    实际上调用的是Student类中_init_方法
    Step 3. 给对象发出消息
    通过给对象发消息让对象完成某些工作
    解决任何问题都是通过让对象去做事情

    实例

    步骤

    # Step 1. 定义类
    # 类是对象的蓝图和模板 有了类就可以创建对象
    # 定义类需要做两件事:数据抽象和行为抽象
    # 数据抽象 - 抽取对象共同的静态特征(找名词)- 属性
    # 行为抽象 - 抽取对象共同的动态特征(找动词)- 方法
    # 定义类的关键字 - class - 类名(每个单词首字母大写)
    
    class Student:
    
        # 构造方法(构造器/构造子 -  construct)
        # 调用该方法时,不是直接使用方法的名字,而是使用类的名字
        def __init__(self, name, age):
            # 给对象绑定属性
            self.__name = name
            self.__age = age
    
        # 我们定义一个方法就代表对象可以接收这个消息
        # 对象的方法的第一个参数都是统一写成self
        # 它代表了接收消息的对象 - 对象.消息(参数)
        def study(self, course):
            print('%s正在学习%s, 年龄%d' % (self.__name, course, self.__age))
    
        def watch_av(self):
            if self.__age >= 18:
                print('%s正在看片, 年龄%d' % (self.__name, self.__age))
            else:
                print('%s我们推荐你看《熊出没》' % self.__name)
    
    
    def main():
        # Step 2. 调用构造方法创建学生对象
        # 实际上调用的是Student类中__init__方法
        stu1 = Student('cfx', 24)
        # Step 3. 给对象发出消息
        # 通过给对象发消息让对象完成某些工作
        # 解决任何问题都是通过让对象去做事情
        stu1.study('python程序设计')
        stu2 = Student('王大锤', 5)
        stu2.__name = '刘备'
        stu2.__age = 20
        stu2.study('HTML')
        stu2.watch_av()
    
    
    if __name__ == '__main__':
        main()
    

    计算矩形的周长和面积

    class Rectangle(object):
    
        def __init__(self, width, hight):
            self._width = int(width)
            self._hight = int(hight)
    
        def peri(self):
            return self._width * 2 + self._hight * 2
    
        def arer(self):
            return self._hight * self._width
    
    
    def main1():
        rect1 = Rectangle('10', '5')
        print(rect1.peri())
        print(rect1.arer())
    
    

    游泳池圆形过道及围栏花费

    from math import pi
    
    # 我们定义一个类实际上是把数据和操作数据的函数绑定到一起
    # 形成了一个逻辑上的整体 这个整体就叫对象
    # 而且将来任何时候想使用这种对象时直接复用这个类就可以了
    class Circle(object):
    
        def __init__(self,radius = 0):
            self._radius = radius
    
        def area(self):
            return pi * self._radius ** 2
    
        def perimeter(self):
            return pi * self._radius * 2
    
    
    def main():
        r = eval(input('请输入游泳池半径:'))
        big = Circle(r + 3)
        small = Circle(r)
        print('围墙的造价为%.2f' % (big.perimeter() * 35.5))
        print('过道的造价为%.2f' % ((big.area()-small.area()) * 25))
    
    
    if __name__ == '__main__':
        main()
    

    移动点和计算两点间距离

    # 定义一个类 提供下面方法
    # 移动点的方法(移动到 and 移动了)
    # 计算一个点到另一个点距离的方法
    class Dot(object):
    
        def __init__(self, x, y):
            self._x = x
            self._y = y
    
        def move(self, x, y):
            self._x += x
            self._y += y
    
        def goto(self, dx, dy):
            self._x = dx          
            self._y = dy
    
        def __str__(self):
            return '%s, %s' % (str(self._x), str(self._y))
    
        def distance(self, other):
            dx = self._x - other._x               # 此处other_x 可以优化
            dy = self._y - other._y
            return (dx ** 2 + dy ** 2) ** 0.5
    
    
    class Calc(object):                           # 和 distance 作用一样
    
        def __init__(self, dot1,dot2):
            self._x1 = dot1._x
            self._y1 = dot1._y
            self._x2 = dot2._x
            self._y2 = dot2._y
    
        def __str__(self):
            return '%f' % (((self._x2 - self._x1) ** 2 + (self._y2 - self._y1) ** 2) ** 0.5)
    
    def main():
        x1 = eval(input('请输入第一个点的x坐标:'))
        y1 = eval(input('请输入第一个点的y坐标:'))
        x2 = eval(input('请输入第二个点的x坐标:'))
        y2 = eval(input('请输入第二个点的y坐标:'))
        dot1 = Dot(x1, y1)
        dot2 = Dot(x2, y2)
        dot1.goto(5, 5)
        dot2.move(-1, -1)
        print(dot1)
        print(dot2)
        print(dot1.distance(dot2))
        calc1 = Calc(dot1, dot2)
        print(calc1)
    
    
    if __name__ == '__main__':
        main()
    

    实时数字时钟

    学习time模块

    _str变量 --- 在调用print函数时自动执行str里面的语句

    import time
    
    
    class Clock(object):
        """数字时钟"""
    
        def __init__(self, hour=0, minute=0, second=0):
            self._hour = hour
            self._minute = minute
            self._second = second
    
        def run(self):
            """走字"""
            self._second += 1
            if self._second == 60:
                self._second = 0
                self._minute += 1
                if self._minute == 60:
                    self._minute = 0
                    self._hour += 1
                    if self._hour == 24:
                        self._hour = 0
    
        # 下面的方法可以获得对象的字符串表示形式
        # 当我们用print打印对象时会自动调用该方法
    
        def __str__(self):
            """显示时间"""
            return '%02d : %02d : %02d' % \
                   (self._hour, self._minute, self._second)
    
    
    def main(h, m, s):
        clock = Clock(h, m, s)
        while True:
            # os.system('cls')
            print(clock)
            time.sleep(1)
            clock.run()
    
    
    if __name__ == '__main__':
            # 开始时自动提取系统时间
        for _ in range(1):
            times = time.asctime()  # time 模块中的asctime不提供参数返回当前时间的字符串
            print(times)
        h = int(times[11:13])
        m = int(times[14:16])
        s = int(times[17:19])
        main(h, m, s)
    
    

    判断两条线是否相交

    分别判断一条线段的两个点是不是在另一条线段所在直线的两边

    class Line(object):
    
        def __init__(self, x1, y1, x2, y2):
            self._x1 = x1
            self._y1 = y1
            self._x2 = x2
            self._y2 = y2
    
        def cross(self, other):
            a = (self._y2 * 10**3 - self._y1 * 10**3) / (self._x2 * 10**3 - self._x1 * 10**3)
            b = (self._y1 *10**9 - int(a *10**6) * self._x1 * 10**3)/10**9
            c = (other._y1 * 10 ** 9 - ((a * 10 ** 3) * (other._x1 * 10 ** 3)) * 10 ** 3 - b * 10 ** 9)/10 ** 9
            d = (other._y2 * 10 ** 9 - ((a * 10 ** 3) * (other._x2 * 10 ** 3)) * 10 ** 3 - b * 10 ** 9)/10 ** 9
            if c <= 0 and d >= 0 or c >= 0 and d <= 0:
                return True
            else:return False
    
        def __str__(self):
            return '点1(%.3f, %.3f);点2(%.3f, %.3f)' % (self._x1, self._y1, self._x2, self._y2)
    
    def main():
        x11 = eval(input('请输入第一点x(最大精确到小数点后3位):'))
        y11 = eval(input('请输入第一点y(最大精确到小数点后3位):'))
        x12 = eval(input('请输入第二点x(最大精确到小数点后3位):'))
        y12 = eval(input('请输入第二点y(最大精确到小数点后3位):'))
        line1 = Line(x11, y11, x12, y12)
        print(line1)
        x21 = eval(input('请输入第一点x(最大精确到小数点后3位):'))
        y21 = eval(input('请输入第一点y(最大精确到小数点后3位):'))
        x22 = eval(input('请输入第二点x(最大精确到小数点后3位):'))
        y22 = eval(input('请输入第二点y(最大精确到小数点后3位):'))
        line2 = Line(x21, y21, x22, y22)
        print(line2)
        if line1.cross(line2) and line2.cross(line1):
            print('相交')
        else:
            print('不相交')
    
            
    if __name__ == '__main__':
        main()
    

    奥特曼打怪兽

    奥特曼打怪兽原创版

    import random, os
    
    
    class Ultraman(object):
        def __init__(self, name, my_bool, strike_one, strike_two, attack_rate):
            self.name = name
            self.energy = 100
            self.my_bool = my_bool
            self.strike_one = strike_one
            self.strike_two = strike_two
            self.attack_rate = attack_rate
    
        def attack(self, other, m_one, two):
    
            if m_one:
                if random.randint(1, 100) <= self.attack_rate:
                    other.m_bool -= self.strike_one
                    return '奥特曼打中%s' % other.name
                else:
                    return '奥特曼没打中%s' % other.name
            elif two and self.energy >= 30:
                if random.randint(1, 100) <= self.attack_rate:
                    other.m_bool -= self.strike_two
                    self.energy -= 30
                    return '奥特曼打中%s' % other.name
                else:
                    self.energy -= 30
                    return '奥特曼没打中%s' % other.name
            else:
                return '能量不足'
    
        def hava_bool(self):
            return self.my_bool > 0
    
        def my_energy(self):
            if self.energy < 100:
                self.energy += 5
    
        def attacked(self):
            return '奥特曼的剩余血量:%d\t奥特曼的剩余能量:%d' % (self.my_bool, self.energy)
    
        def __str__(self):
            return '奥特曼的属性:%s\t血量:%d\t普通攻击力:%d\t强攻攻击力:%d\t攻击率:%d\t能量:%d' % \
              (self.name, self.my_bool, self.strike_one, self.strike_two, self.attack_rate, self.energy)
    
    
    class Monster(object):
        def __init__(self,name):
            self.name = name
            self.m_bool = 100
            self.strike = random.randint(10,20)
            self.attack_rate = random.randint(50,85)
    
        def attack(self, other):
            if random.randint(1, 100) <= self.attack_rate:
                other.my_bool -= self.strike
                return '%s打中奥特曼' % self.name
            else:
                return '%s没打中奥特曼' % self.name
    
        def hava_bool(self):
            if self.m_bool > 0:
                return True
            else:
                return False
    
        def attacked(self):
            return '%s剩余血量%d' % (self.name, self.m_bool)
    
        def __str__(self):
            return '小怪兽的属性:%s\t血量:%d\t攻击力:%d\t攻击率:%d' % \
                   (self.name, self.m_bool, self.strike, self.attack_rate)
    
    
    def main():
        a = ['总血量','普通攻击力','强攻攻击力','攻击率(1,100)']
        for i in range(4):
            a.append(eval(input('请设置奥特曼%s' % a[i])))
        automan = Ultraman('automan', a[4], a[5], a[6], a[7])
        n = eval(input('你需要设置几个小怪兽:'))
        b1 = ['monster' + '%s' % (v + 1) for v in range(n)]
        for k in range(n):
            b1[k] = Monster(b1[k])
        os.system('cls')
        print(automan)
        for v in range(n):
            print(b1[v])
        method = input('''
        单挑 <--- 1
        群挑 <--- 2
        请输入进攻方式:''')
        if method == '1':
            for f in range(n):
                kk = 1
                os.system('cls')
                while automan.hava_bool() and b1[f].hava_bool():
                    g = input('''第%d回合
                    请选择进攻方式:
                    普攻 <--- 1
                    强攻 <--- 2''' % kk)
                    one = True
                    two = True
                    if g == '1':
                        two = False
                    elif g == '2':
                        one = False
                    print(automan.attack(b1[f], one, two))
                    print(b1[f].attack(automan))
                    if b1[f].hava_bool():
                        print(b1[f].attacked())
                    else:
                        print('%s剩余血量0' % b1[f].name)
                    if automan.hava_bool():
                        print(automan.attacked())
                    else:
                        print('奥特曼剩余血量0,奥特曼输了')
                        break
                    automan.my_energy()
                    go = input('''是否进入下一回合:
                              是<---1
                              否<---2''')
                    if go == '2':
                        break
                    else:
                        os.system('cls')
                    kk += 1
                if f < n-1 and automan.hava_bool() and go != '2':
                    print('奥特曼打死了%s,继续攻打下一只小怪兽' % b1[f].name)
                elif automan.hava_bool() and go != '2':
                    print('奥特曼打死了%s,奥特曼赢了,游戏结束' % b1[f].name)
    
        elif method == '2':
            go_on = True
            kk = 1
            os.system('cls')
            s = n
            while go_on:
                g = input('''第%d回合
                请选择进攻方式:
                普攻 <--- 1
                强攻 <--- 2''' % kk)
                one = True
                two = True
                if g == '1':
                    two = False
                elif g == '2':
                    one = False
                for f in range(n):
                    if automan.hava_bool() and b1[f].hava_bool():
                        print(automan.attack(b1[f], one, two))
                        automan.my_energy()
                        if b1[f].hava_bool():
                            print(b1[f].attacked())
                        else:
                            print('%s剩余血量0,被打死了' % b1[f].name)
                            s -= 1
                if s == 0:
                    print('所有小怪兽都死了,奥特曼胜利')
                    go_on = False
                for h in range(n):
                    if b1[h].hava_bool() and automan.hava_bool():
                        print(b1[h].attack(automan))
                        if automan.hava_bool():
                            print(automan.attacked())
                        else:
                            print('奥特曼剩余血量0,奥特曼输了')
                            go_on =False
                go = input('''是否进入下一回合:
                是<---1
                否<---2''')
                if go =='2':
                    break
                else:
                    os.system('cls')
                kk += 1
    
    
    if __name__ == '__main__':
        main()
    

    奥特曼打怪兽修改版

    通过_slots_魔法限定对象可以绑定的成员变量
    _slots_不能继承,如果想子类有此特性,需要在子类重新写

    from abc import ABCMeta, abstractmethod
    from random import randint, randrange
    
    
    class Fighter(object, metaclass=ABCMeta):
        """战斗者"""
    
        # 通过__slots__魔法限定对象可以绑定的成员变量  
        # __slots__不能继承,如果想子类有此特性,需要在子类重新写
        __slots__ = ('_name', '_hp')
    
        def __init__(self, name, hp):
            """
            初始化方法
    
            :param name: 名字
            :param hp: 生命值
            """
            self._name = name
            self._hp = hp
    
        # 属性访问器
        @property
        def name(self):
            return self._name
    
        # 属性访问器
        @property
        def hp(self):
            return self._hp
    
        # 属性修改器
        @hp.setter
        def hp(self, hp):
            self._hp = hp if hp >= 0 else 0
    
        @property
        def alive(self):
            return self._hp > 0
    
        @abstractmethod
        def attack(self, other):
            """
            攻击
    
            :param other: 被攻击的对象
            """
            pass
    
    
    class Ultraman(Fighter):
        """奥特曼"""
    
        __slots__ = ('_name', '_hp', '_mp')
    
        def __init__(self, name, hp, mp):
            """
            初始化方法
    
            :param name: 名字
            :param hp: 生命值
            :param mp: 魔法值
            """
            super().__init__(name, hp)
            self._mp = mp
    
        def attack(self, other):
            other.hp -= randint(15, 25)
    
        def huge_attack(self, other):
            """
            究极必杀技(打掉对方至少50点或四分之三的血)
    
            :param other: 被攻击的对象
    
            :return: 使用成功返回True否则返回False
            """
            if self._mp >= 50:
                self._mp -= 50
                injury = other.hp * 3 // 4
                injury = injury if injury >= 50 else 50
                other.hp -= injury
                return True
            else:
                self.attack(other)
                return False
    
        def magic_attack(self, others):
            """
            魔法攻击
    
            :param others: 被攻击的群体
    
            :return: 使用魔法成功返回True否则返回False
            """
            if self._mp >= 20:
                self._mp -= 20
                for temp in others:
                    if temp.alive:
                        temp.hp -= randint(10, 15)
                return True
            else:
                return False
    
        def resume(self):
            """恢复魔法值"""
            incr_point = randint(1, 10)
            self._mp += incr_point
            return incr_point
    
        def __str__(self):
            return '~~~%s奥特曼~~~\n' % self._name + \
                '生命值: %d\n' % self._hp + \
                '魔法值: %d\n' % self._mp
    
    
    class Monster(Fighter):
        """小怪兽"""
    
        __slots__ = ('_name', '_hp')
    
        def attack(self, other):
            other.hp -= randint(10, 20)
    
        def __str__(self):
            return '~~~%s小怪兽~~~\n' % self._name + \
                '生命值: %d\n' % self._hp
    
    
    def is_any_alive(monsters):
        """判断有没有小怪兽是活着的"""
        for monster in monsters:
            if monster.alive:
                return True
        return False
    
    
    def select_alive_one(monsters):
        """选中一只活着的小怪兽"""
        monsters_len = len(monsters)
        while True:
            index = randrange(monsters_len)
            monster = monsters[index]
            if monster.alive:
                return monster
    
    
    def display_info(ultraman, monsters):
        """显示奥特曼和小怪兽的信息"""
        print(ultraman)
        for monster in monsters:
            print(monster, end='')
    
    
    def main():
        u = Ultraman('骆', 1000, 120)
        m1 = Monster('舒', 250)
        m2 = Monster('白元芳', 500)
        m3 = Monster('王大锤', 750)
        ms = [m1, m2, m3]
        fight_round = 1
        while u.alive and is_any_alive(ms):
            print('========第%02d回合========' % fight_round)
            m = select_alive_one(ms)  # 选中一只小怪兽
            skill = randint(1, 10)   # 通过随机数选择使用哪种技能
            if skill <= 6:  # 60%的概率使用普通攻击
                print('%s使用普通攻击打了%s.' % (u.name, m.name))
                u.attack(m)
                print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
            elif skill <= 9:  # 30%的概率使用魔法攻击(可能因魔法值不足而失败)
                if u.magic_attack(ms):
                    print('%s使用了魔法攻击.' % u.name)
                else:
                    print('%s使用魔法失败.' % u.name)
            else:  # 10%的概率使用究极必杀技(如果魔法值不足则使用普通攻击)
                if u.huge_attack(m):
                    print('%s使用究极必杀技虐了%s.' % (u.name, m.name))
                else:
                    print('%s使用普通攻击打了%s.' % (u.name, m.name))
                    print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
            if m.alive:  # 如果选中的小怪兽没有死就回击奥特曼
                print('%s回击了%s.' % (m.name, u.name))
                m.attack(u)
            display_info(u, ms)  # 每个回合结束后显示奥特曼和小怪兽的信息
            fight_round += 1
        print('\n========战斗结束!========\n')
        if u.alive > 0:
            print('%s奥特曼胜利!' % u.name)
        else:
            print('小怪兽胜利!')
    
    
    if __name__ == '__main__':
        main()
    
    

    可变参数、关键字参数、命名关键字参数

    • 可变参数 - 元组
      同样,如果想把一个元组当作可变参数传入,也需要在参数前加一个*
    • 关键字参数 - 字典 - 根据参数名来决定如何执行
      如果希望把一个字典当作关键词参数传入 需要在参数前放两个*
    • 命名关键字参数
      *号后面的参数必须要写成关键字参数形式,
      前面的可以给关键字参数形式也可以给可变参数形式,但关键字参数形式必须在可变参数后
    # 关键字参数  -  字典  -  根据参数名来决定如何执行
    # 可变参数  -  元组
    def say_hello(*args,**kwargs):
        print(args)
        print(kwargs)
        if 'name' in kwargs:
            print('你好,%s' % kwargs['name'])
        elif 'age' in kwargs:
            age = kwargs['age']
            if age <= 16:
                print('你还是个小屁孩')
            else:
                print('你是一个成年人')
        else:
            print('请提供个人信息')
    
    
    # 命名关键字参数
    # *号后面的参数必须要写成关键字参数形式,
    # 前面的可以给关键字参数形式也可以给可变参数形式,但关键字参数形式必须在可变参数后面
    def foo(a, b, c, *, name, age):
        print(a + b + c)
        print(name, ':', age)
    
    def main():
        say_hello(1,2,'hello',name='cfx',age=24, qq=12345689, gender=True)
        param = {'name': '王大锤', 'age': 330, 'qq': 12345689, 'gender': True}
        # say_hello(param)      #  会报错
        #  如果希望把一个字典当作关键词参数传入  需要在参数前放两个*
        say_hello(**param)
        #  同样,如果想把一个元组当作可变参数传入,也需要在参数前加一个*
        tuple1 = (5, 2, 'good')
        say_hello(*tuple1,**param)
    
        foo(a=1, b=2, c=3, name='cfx', age=24)
        foo(1, 2, 3, name='cfx', age=24)
    
    
    if __name__ == '__main__':
        main()
    

    装饰器

    通过装饰器修饰f函数 让f函数在执行过程中可以做更多额外的操作

    # 高内聚,低耦合
    
    
    # 通过向函数中传入函数,可以写出更通用的代码
    # calc函数中的第二个参数是另一个函数,它代表了一个二元运算
    # 这样calc函数就不需要根某一特定的二元运算耦合在一起,
    # 所以calc函数变得通用性更强,可以由传入的第二个参数来决定到底做什么
    def calc(my_list, op):
        total = my_list[0]
        for index in range(1, len(my_list) - 1):
            total = op(my_list[index], total)
        return total
    
    
    def add(x, y):
        return x + y
    
    
    def mul(x, y):
        return x * y
    
    
    def record(fn):
        def wrapper(*args, **kwargs):
            print('准备执行%s函数' % fn.__name__)
            print(args)
            print(kwargs)
    
            # 此行代码在执行被装饰的函数
            # 在这行代码的前后我们可以附加其他的代码
            # 这些代码可以让我们在执行函数时做一些额外的工作
            val = fn(*args, **kwargs)
    
            print('%s函数执行完成' % fn.__name__)
            print('返回了%d' % val)
            # 返回被装饰的函数的执行结果
            return val
        return wrapper
    
    
    # 通过装饰器修饰f函数 让f函数在执行过程中可以做更多额外的操作
    @record
    def f(n):
        if n == 0 or n == 1:
            return 1
        else:
            return n * f(n-1)
    
    
    if __name__ == '__main__':
        print(f(5))
        my_list = [1, 3, 5, 7, 8]
        print(calc(my_list, add))
        print(calc(my_list, mul))
    

    继承、抽象类、抽象方法

    # 线段上有两个点 - has-a - 关联
    # 人使用了房子 - use-a - 依赖
    # 学生是人 - is-a - 继承
    # 继承 - 从已经有的类创建新类的过程
    # 提供继承信息的称为父类(超类/基类)
    # 得到继承信息的称为子类(派生类/衍生类)
    # 通过继承我们可以将子类中的重复代码抽取到父类中
    # 子类通过继承并复用这些代码来减少重复代码的编写
    # 将来如果要维护子类的公共代码只需要在父类中操作就可以了
    # 调用super().__init__(name,age,……)来绑定父类属性到子类
    
    # 方法重写(override)- 覆盖 / 置换
    # 子类在继承父类方法后对方法进行了重新实现
    #  super().watch_av() # 传入父类方法的函数
    # 当我们给子类对象发送watch_av消息时执行的是子类重写过的方法
    
    # python没有从语言层面支持抽象的概念
    # 我们可以通过abc模块来制造抽象类的效果
    # 在定义类的时候通过制定metaclass=ABCMeta可以将类声明为抽象类
    # 抽象类是不能创建对象的 抽象类存在的意义是专门拿给其他类继承
    # abc模块中还有一个包装器abstractmethod
    # 通过这个包装器可以将方法包装为抽象方法 必须要求子类进行重写
    from abc import ABCMeta, abstractmethod
    
    
    class Employee(object, metaclass=ABCMeta):
        """员工"""
        def __init__(self, name):
            """初始化方法"""
            self._name = name
    
        @property
        def name(self):
            return self._name
    
        @abstractmethod
        def get_salary(self):
            """获得月薪"""
            pass
    
    
    class Manager(Employee,object):
        """部门经理"""
        def get_salary(self):
            return 15000
    
    
    class Programmer(Employee):
        def __init__(self, name, working_hour = 0):
            # 子类重新定义了__init__后系统就会选用子类的__init__
            # 如果还需要父类的初始化属性需要添加super().__init__(……)
            super().__init__(name)
            self._working_hour = working_hour
    
        @property
        def working_hour(self):
            return self._working_hour
    
        @working_hour.setter
        def working_hour(self, working_hour):
            self._working_hour = working_hour \
                if working_hour > 0 else 0
    
        def get_salary(self):
            return self.working_hour * 150
    
    
    class Salesman(Employee):
        def __init__(self, name):
            super().__init__(name)
            self._sales = 0
    
        @property
        def sales(self):
            return self._sales
    
        @sales.setter
        def sales(self, sales):
            self._sales = sales if sales > 0 else 0
    
        def get_salary(self):
            return 1200 + self._sales * 0.05
    
    
    def main():
        emps = [
            Manager('刘备'), Programmer('诸葛亮'),
            Manager('曹操'), Salesman('卢布'),
            Programmer('赵云'), Salesman('荀彧')
        ]
        for emp in emps:
            if isinstance(emp, Programmer):
                emp.working_hour = eval(input('请输入%s本月工作时间:' % emp.name))
            elif isinstance(emp, Salesman):
                emp.sales = float(input('请输入%s本月销售额:' % emp.name))
            # 同样是接收get_salary这个消息,但是不同的员工表现出了不同的行为
            # 因为三个子类都重写了get_salary方法,所以这个方法会表现出多态行为
            print('%s本月工资为:¥%.2f' % (emp.name, emp.get_salary()))
    
    
    if __name__ == '__main__':
        main()
    

    实例

    计算矩形面积和周长

    class Rectangle(object):
    
        __slots__ = ('_width', '_hight')
        def __init__(self, width, hight):
            self._width = eval(width)
            self._hight = eval(hight)
    
        @property
        def width(self):
            return self._width
    
        @width.setter
        def width(self, width):
            self._width = width if width > 0 else 0
    
        @property
        def hight(self):
            return self._hight
    
        @width.setter
        def width(self, hight):
            self._hight = hight if width > 0 else 0
    
        def peri(self):
            return self._width * 2 + self._hight * 2
    
        def arer(self):
            return self._hight * self._width
    
    
    if __name__ == '__main__':
        rect1 = Rectangle('10', '5')
        print(rect1.peri())
        print(rect1.arer())
        width = 20
        hight = 30
        print(rect1.peri())
        print(rect1.arer())
    

    模拟银行账户功能

    class Account(object):
        def __init__(self, *, card_no, owner, banlance = 0):
            # *号后面的参数必须要写成关键字参数形式,
            self._card_no = card_no
            self._woner = owner
            self._banlance = banlance
    
        @property
        def banlance(self):
            return self._banlance
    
        def deposit(self, money):
            if money > 0:
                self._banlance += money
                return True
            return False
    
        def withdrow(self, money):
            if 0 < money <= self._banlance:
                self._banlance -= money
                return True
            return False
    
        def transfer(self, other, money):
            if self.withdrow(money):
                other.deposit(money)
                return True
            return False
    
    
    def main():
        account = Account(card_no='12245', owner='王凯')
        account1 = Account(card_no='35222', owner='凯fjs')
        print(account.banlance)
        account.deposit(900)
        print(account1.banlance)
        print(account.banlance)
        if account.transfer(account1,1000):
            print(account1.banlance)
            print(account.banlance)
        else:
            print('余额不足')
    
        if account.transfer(account1,200):
            print(account1.banlance)
            print(account.banlance)
        else:
            print('余额不足')
    
    
    if __name__ == '__main__':
        main()
    

    定义一副扑克

    from random import randrange
    
    
    class Card(object):
        """一张牌"""
        def __init__(self, suite, face):
            self._suite = suite
            self._face = face
    
        @property
        def face(self):
            return self._face
    
        @property
        def suite(self):
            return self._suite
    
        def __str__(self):
            if self._face == 14:
                face_str = 'A'
            elif self._face == 11:
                face_str = 'J'
            elif self._face == 12:
                face_str = 'Q'
            elif self._face == 13:
                face_str = 'K'
            else:
                face_str = str(self._face)
            return '%s%s' % (self._suite, face_str)
    
    class Poker(object):
        """一副牌"""
        def __init__(self):
            self._current = 0
            self._cards = []
            for suite in '♠♥♣♦':
                for face in range(2, 15):
                    card = Card(suite, face)
                    self._cards.append(card)
    
        @property
        def cards(self):
            return self._cards
    
        def shuffle(self):
            """洗牌"""
            cards_len = len(self._cards)
            for index in range(cards_len):
                pos = randrange(cards_len)
                self._cards[index], self._cards[pos] = \
                    self._cards[pos], self._cards[index]
    
        @property
        def next(self):
            """发牌"""
            card = self._cards[self._current]
            self._current += 1
            return card
    
        @property
        def has_next(self):
            """还有没有牌"""
            return self._current < len(self.cards)
    
    
    
    class Player(object):
        def __init__(self, name):
            self._name = name
            self._cards_on_hand = []
    
        @property
        def name(self):
            return self._name
    
        @property
        def hava(self):
            return self._cards_on_hand
    
        def get(self, card):
            self._cards_on_hand.append(card)
    
        def arrange(self):
            self._cards_on_hand.sort(key=get_key)
    
    
    def get_key(card):
        return card.face
    
    
    
    def main():
        p = Poker()
        p.shuffle()
        players = [
            Player('东邪'), Player('西毒'),
            Player('南帝'), Player('北丐')
        ]
        while p.has_next:
            for player in players:
                player.get(p.next)
        for player in players:
            player.arrange()
            print(player.name +':', end=' ')
            for cards in player.hava:
                print(cards, end='\t')
            print('')
    
    
    
    if __name__ == '__main__':
        main()
    

    21点扑克牌游戏(游戏)

    需要用到上面定义的扑克牌

    from poker import *
    
    
    def cacl(list1):
        list2 = []
        for card in list1:
            if card.face == 11:
                list2.append(10)
            elif card.face == 12:
                list2.append(10)
            elif card.face == 13:
                list2.append(10)
            elif card.face == 14:
                list2.append(11)
                if sum(list2) > 21:
                    list2.pop()
                    list2.append(1)
            else:
                list2.append(int(card.face))
        if sum(list2) > 21 :
            for key in list2:
                if key == 11:
                    list2.append(-10)
        return sum(list2)
    
    
    def display(player):
        print('%s: ' % player.name, end='')
        for key in player.hava:
            print(key, end=' ')
        print('点数为:%d' % cacl(player.hava), end=' ')
    
    
    def winer(player, m_player):
        if cacl(m_player.hava) <= 21:
            if cacl(m_player.hava) < cacl(player.hava) <=21:
                display(player)
                print('赢了')
            elif cacl(player.hava) > 21:
                display(player)
                print('爆了')
            elif cacl(player.hava) == cacl(m_player.hava):
                display(player)
                print('平局')
            else:
                display(player)
                print('输了')
        else:
            if cacl(player.hava) <= 21:
                display(player)
                print('赢了')
            elif cacl(player.hava) > 21:
                display(player)
                print('平局')
    
    
    def main():
        p = Poker()
        p.shuffle()
        players = [
            Player('庄家'), Player('玩家1'),  Player('玩家2'),  Player('玩家3')
        ]
        while p.has_next:
            for i in range(2):
                players[0].get(p.next)
                p.cards.remove(players[0].hava[-1])
                if i == 0:
                    print('%s:' % players[0].name, players[0].hava[i], end=' ')
                elif i == 1:
                    print('*')
            for player in players[1:]:
                for i in range(2):
                    player.get(p.next)
                    p.cards.remove(player.hava[-1])
                display(player)
                print()
            for player in players[1:]:
                while cacl(player.hava) <= 21:
                    go_on = input('%s是否继续拿牌?(y/n)' % player.name)
                    if go_on == 'y':
                        player.get(p.next)
                        p.cards.remove(player.hava[-1])
                        display(player)
                        print()
                    elif go_on == 'n':
                        break
            print('\n庄家继续拿牌')
            while cacl(players[0].hava) < 17:
                players[0].get(p.next)
                p.cards.remove(players[0].hava[-1])
            print('=================================')
            display(players[0])
            print()
            for player in players[1:]:
                winer(player, players[0])
            break
    
    
    if __name__ == '__main__':
        main()
    

    实现分数的加减乘除(运算符重载,集联编程)

    # 运算符重载(重写)
    # 集联编程
    from math import gcd
    
    
    class Fraction(object):
    
        def __init__(self, num, den):
            if den == 0:
                raise ValueError('分母不能为0')
            self._num = num
            self._den = den
            # self.normalize()
            # self.simplify()
    
        @property
        def num(self):
            return self._num
    
        @property
        def den(self):
            return self._den
    
        def normalize(self):
            """标准化"""
            if self._den < 0:
                self._den = -self._den
                self._num = -self._num
            return self                    # 返回self后才能集联编程
    
        def simplify(self):
            """化简"""
            if self._num != 0 and self._den != 1:
                factor = gcd(abs(self._den), abs(self._num))
                if factor > 1:
                    self._num //= factor
                    self._den //= factor
            return self                    # 返回self后才能集联编程
    
        def add(self, other):
            return Fraction(self._num * other.den + self._den * other.num, self._den * other.den).simplify().normalize()
    
        def sub(self, other):
            return Fraction(self._num * other.den - self._den * other.num, self._den * other.den).simplify().normalize()
    
        def mul(self, other):
            return Fraction(self._num * other.num, self._den * other.den).simplify().normalize()
    
        def div(self, other):
            return Fraction(self._num * other.den, self._den * other.num).simplify().normalize()
    
        def __add__(self, other):
            return self.add(other)
    
        def __sub__(self, other):
            return self.sub(other)
    
        def __mul__(self, other):
            return self.mul(other)
    
        def __truediv__(self, other):
            return self.div(other)
    
        def __str__(self):
            if self._num == 0:
                return '0'
            elif self._den == 1:
                return str(self._num)
            else:
                return '%d/%d' % (self._num, self._den)
    
    
    def main():
       f1 = Fraction(-7, 25)
       f2 = Fraction(-7, 35)
       print(f1 + f2)
       print(f1 - f2)
       print(f1 * f2)
       print(f1 / f2)
    
    
    if __name__ == '__main__':
        main()
    

    五子棋(游戏)

    import pygame
    
    EMPTY = 0
    BLACK = 1
    WHITE = 2
    
    black_color = [0, 0, 0]
    white_color = [255, 255, 255]
    
    
    class RenjuBoard(object):
    
        def __init__(self):
            self._board = [[0 for _ in range(15)] for __ in range(15)]   # 创建15个空列表的列表
            self.reset()
    
        def reset(self):
            for row in range(len(self._board)):
                self._board[row] = [EMPTY] * 15  # 清除棋盘所有棋子
    
        def check(self, row, col): # 判断输赢
            q = 1
            for i in range(1, 5):
                if row + i <= 14 and self._board[row][col] == self._board[row + i][col]:
                    q += 1
                elif row - i >= 0 and self._board[row][col] == self._board[row - i][col]:
                    q += 1
                else:
                    q = 1
                if q >= 5:
                    return True
            for i in range(1, 5):
                if col + i <= 14 and self._board[row][col] == self._board[row][col + i]:
                    q += 1
                elif col - i >= 0 and self._board[row][col] == self._board[row][col - i]:
                    q += 1
                else:
                    q = 1
                if q >= 5:
                    return True
            for i in range(1, 5):
                if row - i >= 0 and col - i >= 0 and self._board[row][col] == self._board[row - i][col - i]:
                    q += 1
                elif row + i <= 14 and col + i <= 14 and self._board[row][col] == self._board[row + i][col + i]:
                    q += 1
                else:
                    q = 1
                if q >= 5:
                    return True
            for i in range(1, 5):
                if row - i >= 0 and col + i <= 14 and self._board[row][col] == self._board[row - i][col + i]:
                    q += 1
                elif row + i <= 14 and col - i >= 0 and self._board[row][col] == self._board[row + i][col - i]:
                    q += 1
                else:
                    q = 1
                if q >= 5:
                    return True
    
        def move(self, row, col, is_black):
            if self._board[row][col] == EMPTY:
                self._board[row][col] = BLACK if is_black else WHITE
                return True
            return False
    
        def draw(self, screen):
            for i in range(40, 640, 40):
                pygame.draw.line(screen, black_color, [40, i], [600, i], 1)
                pygame.draw.line(screen, black_color, [i, 40], [i, 600], 1)  # 画线 做棋盘
            pygame.draw.rect(screen, black_color, [36, 36, 568, 568], 4)  # 画矩形 36,36 表示起点 568 , 568 表示宽高 4 表示宽度
            pygame.draw.circle(screen, black_color, [320, 320], 5, 0)  # 绘制中心 5 为半径 0 为实心 1 为空心
            for i in range(160, 481, 320):
                for j in range(160, 481, 320):
                    pygame.draw.circle(screen, black_color, [i, j], 5, 0)  # 绘制其他四个点
            for row in range(len(self._board)):
                for col in range(len(self._board[row])):
                    if self._board[row][col] != EMPTY:
                        ccolor = black_color \
                            if self._board[row][col] == BLACK else white_color
                        pos = [40 * (col + 1), 40 * (row + 1)]
                        pygame.draw.circle(screen, ccolor, pos, 20, 0)
    
    
    def main():
        black_win = pygame.image.load('win.jpg')  # 加载图片
        white_win = pygame.image.load('fall.jpg')
        board = RenjuBoard()
        is_black = True
        pygame.init() # 初始化
        pygame.display.set_caption('五子棋') # 设置标题
        screen = pygame.display.set_mode([640, 640]) # 设置屏幕大小
        screen.fill([255, 255, 0]) # 设置背景颜色
        board.draw(screen) # 绘制棋盘
        pygame.display.flip() # 刷新界面显示
        running = ok = True
        while running:
            for event in pygame.event.get(): #捕获所有事件,鼠标|键盘
                if event.type == pygame.QUIT: # 捕获点击退出事件
                    running = False
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_q: # 捕获按下键盘q键
                    board.reset() # 重置棋盘及棋子
                    is_black = True # 重置棋色
                    screen.fill([255, 255, 0]) # 重置背景颜色
                    board.draw(screen) # 绘制棋盘及棋子(开始无棋子)
                    pygame.display.flip() # 刷新出界面
                elif event.type == pygame.MOUSEBUTTONDOWN\
                        and event.button == 1: # 单机鼠标添加棋子
                    x, y = event.pos  # 获取点击位置
                    if 40 <= x <= 640 and 40 <= y <= 640: # 判断是点击位置是不是在棋盘上
                        row = round((y - 40) / 40)
                        col = round((x - 40) / 40)
                        if board.move(row, col, is_black):
                            is_black = not is_black
                            screen.fill([255, 255, 0])
                            board.draw(screen)
                            if board.check(row, col):
                                if not is_black: # 白棋赢显示的图片
                                    screen.blit(black_win, (0, 20), (20, 0,800,800))
                                elif is_black: # 黑棋赢显示的图片
                                    screen.blit(white_win, (90, 0), (40, 0,600,600))
                            if ok:
                                pygame.display.flip()
    
        pygame.quit()
    
    
    if __name__ == '__main__':
        main()
    ·
    

    大球吃小球(游戏)

    from random import randint
    import math
    import pygame
    
    
    class Ball(object):
    
        def __init__(self, center, color, radius, speed):
            self._center = center
            self._color = color
            self._radius = radius
            self._speed = speed
    
        @property
        def center(self):
            return self._center
    
        @property
        def radius(self):
            return self._radius
    
        @radius.setter
        def radius(self, new):
            self._radius = new
    
        def cross(self, other): # 判断一个球是否与另一个球重合,如果是,增加大球面积,让小球面积变为零
            x, y = self._center[0], self._center[1]
            x1, y1 = other.center[0], other.center[1]
            if math.sqrt((y1 - y) ** 2 + (x1 - x) ** 2) <= abs(self._radius - other.radius):
                if self._radius > other.radius:
                    self.radius = int(math.sqrt(self._radius ** 2 + other.radius ** 2))
                    other.radius = 0
                else:
                    other.radius = int(math.sqrt(self._radius ** 2 + other.radius ** 2))
                    self.radius = 0
    
        def move(self): # 更改每个球的坐标,实现移动,并在边界弹回来
            x, y = self._center[0], self._center[1]
            sx, sy = self._speed[0], self._speed[1]
            self._center = x, y = x + sx, y + sy
            if x + self._radius >= 800:
                self._speed = -abs(sx), sy
            elif x - self._radius <= 0:
                self._speed = abs(sx), sy
            if y + self._radius >= 600:
                self._speed = sx,-abs(sy)
            elif y - self._radius <= 0:
                self._speed = sx,abs(sy)
    
        def draw(self, screen): # 画出球
            pygame.draw.circle(screen, self._color, self._center,
                               self._radius, 0)
    
    
    def main():
        balls = []
        pygame.init()
        screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption('大球吃小球')
        clock = pygame.time.Clock() # 设置一个计时器
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN \
                        and event.button == 1:
                    color = random_color()
                    radius = randint(10, 100) # 球的半径
                    speed = randint(-10, 10), randint(-10, 10) # 球x,y方向的移动速度及方向
                    ball = Ball(event.pos, color, radius, speed)
                    balls.append(ball)
            refresh(screen, balls)
            clock.tick(24) # 一秒刷新24次
            for ball in balls:
                ball.move() # 每个球开始移动
            if len(balls) >= 2:
                for num in range(len(balls)):
                    for num1 in range(num + 1, len(balls)):
                        balls[num].cross(balls[num1]) #判断两个球是否重合,重合就吃掉小球,打球面积增加
        pygame.quit()
    
    
    def refresh(screen, balls): # 刷新窗口界面
        bg_color = (240, 255, 240)
        screen.fill(bg_color)
        for ball in balls:
            ball.draw(screen)
        pygame.display.flip()
    
    
    def random_color(): # 随机产生颜色
        red = randint(0, 255)
        green = randint(0, 255)
        blue = randint(0, 255)
        return red, green, blue
    
    
    if __name__ == '__main__':
        main()
    
    

    贪吃蛇(游戏)

    from abc import ABCMeta, abstractmethod
    from random import randint
    import pygame
    
    FOOD_COLOR = (51, 221, 43)
    WALL_COLOR = (255, 0, 0)
    GREEN_COLOR = (0, 255, 0)
    UP = 0
    RIGHT = 1
    DOWN = 2
    LEFE = 3
    
    
    class GameObject(object, metaclass=ABCMeta):
        # 抽象类
        def __init__(self, x, y, color):
            self._color = color
            self._x = x
            self._y = y
    
        @abstractmethod # 抽象方法,子类必须拥有此方法
        def draw(self, screen):
            pass
    
        @property
        def x(self):
            return self._x
    
        @property
        def y(self):
            return self._y
    
    
    class Wall(GameObject):
        def __init__(self, x, y, width, height, color=WALL_COLOR):
            super().__init__(x, y, color)
            self._width = width
            self._height = height
    
        @property
        def width(self):
            return self._width
    
        @property
        def height(self):
            return self._height
    
        def draw(self, screen): # 画出边框 也就是墙
            pygame.draw.rect(screen, self._color, (self._x, self._y, self._width, self._height), 5)
            # (屏幕,颜色,(起点x坐标,起点y坐标,宽度,高度),线宽)
            
    
    class Food(GameObject):
        def __init__(self, x, y, size, color=FOOD_COLOR):
            super(Food, self).__init__(x, y, color)
            self._size = size
            self._show = True
    
        def new_dot(self):
            dot = [x for x in range(10, 610, 20)]
            self._x = dot[randint(0, len(dot) - 1)]
            self._y = dot[randint(0, len(dot) - 1)]
    
        def draw(self, screen): # 画食物,食物的坐标点是其左上角的点
            if self._show:
                pygame.draw.circle(screen, self._color,
                                   (self._x + self._size // 2, self._y + self._size // 2), self._size // 2, 0)
                # (屏幕,颜色,(圆点x坐标,圆点y坐标),半径,实心0 or 空心1)
            self._show = not self._show
    
    
    class SnakeNode(GameObject):
        # x, y 必须为基数(左上角坐标点),因为蛇移动的窗口的左上角坐标为(0,0)
        def __init__(self, x, y, size, color=GREEN_COLOR):
            super().__init__(x, y, color)
            self._size = size
    
        @property
        def size(self):
            return self._size
    
        def draw(self, screen): # 绘制蛇的节点和每个节点的边框
            pygame.draw.rect(screen, self._color, (self._x, self._y, self._size, self._size), 0)
            pygame.draw.rect(screen, (230, 255, 230), (self._x, self._y, self._size, self._size), 1)
    
    
    class Snake(object): # 不能继承蛇的节点SnakeNode,蛇上有蛇的节点 是has a 关联关系 非继承关系
        def __init__(self):
            """
            定义蛇默认移动方向和长度
            """
            self._dir = LEFE
            self._nodes = []
            # 装蛇的每个节点,利用append向后依次装载
            for index in range(10):
                node = SnakeNode(290 + index * 20, 250, 20)
                self._nodes.append(node)
    
        @property
        def dir(self):
            return self._dir
    
        def change_dir(self, new_dir):
            """
            改变蛇的方向
            :param new_dir: 新的方向
            :return: 返回新的方向,如果新方向是原来方向或者原来方向的反方向则不返回
            """
            if (self._dir + new_dir) % 2 != 0:
                self._dir = new_dir
    
        def move(self):
            head = self._nodes[0]
            snake_dir = self._dir
            x, y, size = head.x, head.y, head.size
            if snake_dir == UP:
                y -= size
            elif snake_dir == RIGHT:
                x += size
            elif snake_dir == DOWN:
                y += size
            else:
                x -= size
            new_head = SnakeNode(x, y, size)
            self._nodes.insert(0, new_head)
            # 每次移动时在列表前面加一个节点,并删除最后一个节点
            self._nodes.pop()
    
        def collide(self, wall):
            """
            判断是否撞墙
            :param wall: 墙
            :return: 撞到返回True 否则返回False
            """
            head = self._nodes[0]
            x, y, size = head.x, head.y, head.size
            return x < wall.x or x > (wall.x + wall.width - size) or y < wall.y or y > (wall.y + wall.width - size)
    
        def eat_food(self, food):
            """
            判断是否吃到食物
            :param food: 食物对象
            :return: 吃到返回True,并记下最后一个节点属性,并加到最后。
            (由于蛇每次移动都会删掉最后一节尾巴并增加新的头,所以相当于此次没有删除蛇尾)
            """
            head = self._nodes[0]
            x, y, size = head.x, head.y, head.size
            if x == food.x and y == food.y:
                tail = self._nodes[-1]
                self._nodes.append(tail)
                return True
    
        def eat_me(self):
            """
            判断蛇是否吃到自己
            :return: 吃到返回True
            """
            head = self._nodes[0]
            x, y, size = head.x, head.y, head.size
            for a_node in self._nodes[4:]:
                ax, ay = a_node.x, a_node.y
                if abs(ax - x) < 20 and ay == y:
                    return True
                if abs(ay - y) < 20 and ax == x:
                    return True
                # 此处不能用elif,因为蛇在移动时不光检测两个方向,而是四个方向
    
        def draw(self, screen):
            """
            画出每个列表中每个节点
            :param screen: 画节点的屏幕
            :return: 可视化图形
            """
            for node in self._nodes:
                node.draw(screen)
    
    
    def main():
        def handle_key_event(key_event):
            
            """
            处理按键事件
            :param key_event: 捕获的键盘事件
            :return: 新的方向
            """
            key = key_event.key
            if key == pygame.K_UP or key == pygame.K_w:
                new_dir = UP
            elif key == pygame.K_RIGHT or key == pygame.K_d:
                new_dir = RIGHT
            elif key == pygame.K_DOWN or key == pygame.K_s:
                new_dir = DOWN
            elif key == pygame.K_LEFT or key == pygame.K_a:
                new_dir = LEFE
            elif key == pygame.K_q:
                reset_game()
                return  # 加上return 让代码执行到此处后 后面的代码不在执行
            else:
                return
            if new_dir != snake.dir:
                snake.change_dir(new_dir)
    
        def reset_game():
            """
            重置游戏
            :return: 最初游戏状态
            (重新对蛇和食物赋值,并清空键盘事件(方向))
            """
            nonlocal snake, food
            snake = Snake()
            food = Food(190, 190, 20)
            pygame.event.clear()
    
        def refresh():
            """刷新游戏窗口"""
            food.draw(screen)
            wall.draw(screen)
            pygame.display.flip()
    
        def display_die():# 死亡后显示Game Over!
            font = pygame.font.SysFont('arial', 32)
            text = font.render('Game Over!', True, (255, 0, 0))
            screen.blit(text, (250, 260))
    
        def display_str(x):# 显示吃到食物数量
            font = pygame.font.SysFont('arial', 32)
            text = font.render('%s' % x, True, (255, 0, 0))
            screen.blit(text, (550, 20))
    
        snake = Snake()
        food = Food(190, 190, 20)
        wall = Wall(10, 10, 600, 600)
        pygame.init()
        screen = pygame.display.set_mode((620, 620))
        pygame.display.set_caption('贪吃蛇')
        screen.fill([244, 244, 244])
        pygame.display.flip()
        clock = pygame.time.Clock()
        running = True
        i = 0
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.KEYDOWN:
                    handle_key_event(event)
            clock.tick(3)
    
            if not snake.collide(wall) and not snake.eat_me():
                snake.draw(screen)
                refresh()
                snake.move()
                #  move 和 refresh的位置不能改变,否则蛇死亡时会停在撞到的下一步
            else:
                display_die() # 此处没让蛇重新画,目的是当显示Game Over时蛇不会停在撞墙的下一步
                refresh()
            if snake.eat_food(food):
                i += 1
                food.new_dot()
            screen.fill([244, 244, 244])
            display_str(i)
        pygame.quit()
    
    
    if __name__ == '__main__':
        main()
    
    

    相关文章

      网友评论

          本文标题:python基础 03

          本文链接:https://www.haomeiwen.com/subject/khjjqftx.html