面向对象

一般步骤

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

实例

步骤

# Step 1. 定义类
# 类是对象的蓝图和模板 有了类就可以创建对象
# 定义类需要做两件事:数据抽象和行为抽象
# 数据抽象 - 抽取对象共同的静态特征(找名词)- 属性
# 行为抽象 - 抽取对象共同的动态特征(找动词)- 方法
# 定义类的关键字 - class - 类名(每个单词首字母大写)class Student:# 构造方法(构造器/构造子 -  construct)# 调用该方法时,不是直接使用方法的名字,而是使用类的名字def __init__(self, name, age):# 给对象绑定属性self.__name = nameself.__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 = 20stu2.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 * 2def arer(self):return self._hight * self._widthdef 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 = radiusdef area(self):return pi * self._radius ** 2def perimeter(self):return pi * self._radius * 2def 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 = xself._y = ydef move(self, x, y):self._x += xself._y += ydef goto(self, dx, dy):self._x = dx          self._y = dydef __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._yreturn (dx ** 2 + dy ** 2) ** 0.5class Calc(object):                           # 和 distance 作用一样def __init__(self, dot1,dot2):self._x1 = dot1._xself._y1 = dot1._yself._x2 = dot2._xself._y2 = dot2._ydef __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 timeclass Clock(object):"""数字时钟"""def __init__(self, hour=0, minute=0, second=0):self._hour = hourself._minute = minuteself._second = seconddef run(self):"""走字"""self._second += 1if self._second == 60:self._second = 0self._minute += 1if self._minute == 60:self._minute = 0self._hour += 1if 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 = x1self._y1 = y1self._x2 = x2self._y2 = y2def 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**9c = (other._y1 * 10 ** 9 - ((a * 10 ** 3) * (other._x1 * 10 ** 3)) * 10 ** 3 - b * 10 ** 9)/10 ** 9d = (other._y2 * 10 ** 9 - ((a * 10 ** 3) * (other._x2 * 10 ** 3)) * 10 ** 3 - b * 10 ** 9)/10 ** 9if c <= 0 and d >= 0 or c >= 0 and d <= 0:return Trueelse:return Falsedef __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, osclass Ultraman(object):def __init__(self, name, my_bool, strike_one, strike_two, attack_rate):self.name = nameself.energy = 100self.my_bool = my_boolself.strike_one = strike_oneself.strike_two = strike_twoself.attack_rate = attack_ratedef attack(self, other, m_one, two):if m_one:if random.randint(1, 100) <= self.attack_rate:other.m_bool -= self.strike_onereturn '奥特曼打中%s' % other.nameelse:return '奥特曼没打中%s' % other.nameelif two and self.energy >= 30:if random.randint(1, 100) <= self.attack_rate:other.m_bool -= self.strike_twoself.energy -= 30return '奥特曼打中%s' % other.nameelse:self.energy -= 30return '奥特曼没打中%s' % other.nameelse:return '能量不足'def hava_bool(self):return self.my_bool > 0def my_energy(self):if self.energy < 100:self.energy += 5def 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 = nameself.m_bool = 100self.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.strikereturn '%s打中奥特曼' % self.nameelse:return '%s没打中奥特曼' % self.namedef hava_bool(self):if self.m_bool > 0:return Trueelse:return Falsedef 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 = 1os.system('cls')while automan.hava_bool() and b1[f].hava_bool():g = input('''第%d回合请选择进攻方式:普攻 <--- 1强攻 <--- 2''' % kk)one = Truetwo = Trueif g == '1':two = Falseelif g == '2':one = Falseprint(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,奥特曼输了')breakautoman.my_energy()go = input('''是否进入下一回合:是<---1否<---2''')if go == '2':breakelse:os.system('cls')kk += 1if 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 = Truekk = 1os.system('cls')s = nwhile go_on:g = input('''第%d回合请选择进攻方式:普攻 <--- 1强攻 <--- 2''' % kk)one = Truetwo = Trueif g == '1':two = Falseelif g == '2':one = Falsefor 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 -= 1if s == 0:print('所有小怪兽都死了,奥特曼胜利')go_on = Falsefor 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 =Falsego = input('''是否进入下一回合:是<---1否<---2''')if go =='2':breakelse:os.system('cls')kk += 1if __name__ == '__main__':main()

奥特曼打怪兽修改版

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

from abc import ABCMeta, abstractmethod
from random import randint, randrangeclass Fighter(object, metaclass=ABCMeta):"""战斗者"""# 通过__slots__魔法限定对象可以绑定的成员变量  # __slots__不能继承,如果想子类有此特性,需要在子类重新写__slots__ = ('_name', '_hp')def __init__(self, name, hp):"""初始化方法:param name: 名字:param hp: 生命值"""self._name = nameself._hp = hp# 属性访问器@propertydef name(self):return self._name# 属性访问器@propertydef hp(self):return self._hp# 属性修改器@hp.setterdef hp(self, hp):self._hp = hp if hp >= 0 else 0@propertydef alive(self):return self._hp > 0@abstractmethoddef attack(self, other):"""攻击:param other: 被攻击的对象"""passclass Ultraman(Fighter):"""奥特曼"""__slots__ = ('_name', '_hp', '_mp')def __init__(self, name, hp, mp):"""初始化方法:param name: 名字:param hp: 生命值:param mp: 魔法值"""super().__init__(name, hp)self._mp = mpdef 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 -= 50injury = other.hp * 3 // 4injury = injury if injury >= 50 else 50other.hp -= injuryreturn Trueelse:self.attack(other)return Falsedef magic_attack(self, others):"""魔法攻击:param others: 被攻击的群体:return: 使用魔法成功返回True否则返回False"""if self._mp >= 20:self._mp -= 20for temp in others:if temp.alive:temp.hp -= randint(10, 15)return Trueelse:return Falsedef resume(self):"""恢复魔法值"""incr_point = randint(1, 10)self._mp += incr_pointreturn incr_pointdef __str__(self):return '~~~%s奥特曼~~~\n' % self._name + \'生命值: %d\n' % self._hp + \'魔法值: %d\n' % self._mpclass 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._hpdef is_any_alive(monsters):"""判断有没有小怪兽是活着的"""for monster in monsters:if monster.alive:return Truereturn Falsedef select_alive_one(monsters):"""选中一只活着的小怪兽"""monsters_len = len(monsters)while True:index = randrange(monsters_len)monster = monsters[index]if monster.alive:return monsterdef 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 = 1while 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 += 1print('\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 totaldef add(x, y):return x + ydef mul(x, y):return x * ydef 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 valreturn wrapper# 通过装饰器修饰f函数 让f函数在执行过程中可以做更多额外的操作
@record
def f(n):if n == 0 or n == 1:return 1else: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, abstractmethodclass Employee(object, metaclass=ABCMeta):"""员工"""def __init__(self, name):"""初始化方法"""self._name = name@propertydef name(self):return self._name@abstractmethoddef get_salary(self):"""获得月薪"""passclass Manager(Employee,object):"""部门经理"""def get_salary(self):return 15000class Programmer(Employee):def __init__(self, name, working_hour = 0):# 子类重新定义了__init__后系统就会选用子类的__init__# 如果还需要父类的初始化属性需要添加super().__init__(……)super().__init__(name)self._working_hour = working_hour@propertydef working_hour(self):return self._working_hour@working_hour.setterdef working_hour(self, working_hour):self._working_hour = working_hour \if working_hour > 0 else 0def get_salary(self):return self.working_hour * 150class Salesman(Employee):def __init__(self, name):super().__init__(name)self._sales = 0@propertydef sales(self):return self._sales@sales.setterdef sales(self, sales):self._sales = sales if sales > 0 else 0def get_salary(self):return 1200 + self._sales * 0.05def 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)@propertydef width(self):return self._width@width.setterdef width(self, width):self._width = width if width > 0 else 0@propertydef hight(self):return self._hight@width.setterdef width(self, hight):self._hight = hight if width > 0 else 0def peri(self):return self._width * 2 + self._hight * 2def arer(self):return self._hight * self._widthif __name__ == '__main__':rect1 = Rectangle('10', '5')print(rect1.peri())print(rect1.arer())width = 20hight = 30print(rect1.peri())print(rect1.arer())

模拟银行账户功能

class Account(object):def __init__(self, *, card_no, owner, banlance = 0):# *号后面的参数必须要写成关键字参数形式,self._card_no = card_noself._woner = ownerself._banlance = banlance@propertydef banlance(self):return self._banlancedef deposit(self, money):if money > 0:self._banlance += moneyreturn Truereturn Falsedef withdrow(self, money):if 0 < money <= self._banlance:self._banlance -= moneyreturn Truereturn Falsedef transfer(self, other, money):if self.withdrow(money):other.deposit(money)return Truereturn Falsedef 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 randrangeclass Card(object):"""一张牌"""def __init__(self, suite, face):self._suite = suiteself._face = face@propertydef face(self):return self._face@propertydef suite(self):return self._suitedef __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 = 0self._cards = []for suite in '♠♥♣♦':for face in range(2, 15):card = Card(suite, face)self._cards.append(card)@propertydef cards(self):return self._cardsdef 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]@propertydef next(self):"""发牌"""card = self._cards[self._current]self._current += 1return card@propertydef has_next(self):"""还有没有牌"""return self._current < len(self.cards)class Player(object):def __init__(self, name):self._name = nameself._cards_on_hand = []@propertydef name(self):return self._name@propertydef hava(self):return self._cards_on_handdef 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.facedef 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':breakprint('\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])breakif __name__ == '__main__':main()

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

# 运算符重载(重写)
# 集联编程
from math import gcdclass Fraction(object):def __init__(self, num, den):if den == 0:raise ValueError('分母不能为0')self._num = numself._den = den# self.normalize()# self.simplify()@propertydef num(self):return self._num@propertydef den(self):return self._dendef normalize(self):"""标准化"""if self._den < 0:self._den = -self._denself._num = -self._numreturn 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 //= factorself._den //= factorreturn 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 pygameEMPTY = 0
BLACK = 1
WHITE = 2black_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 = 1for i in range(1, 5):if row + i <= 14 and self._board[row][col] == self._board[row + i][col]:q += 1elif row - i >= 0 and self._board[row][col] == self._board[row - i][col]:q += 1else:q = 1if q >= 5:return Truefor i in range(1, 5):if col + i <= 14 and self._board[row][col] == self._board[row][col + i]:q += 1elif col - i >= 0 and self._board[row][col] == self._board[row][col - i]:q += 1else:q = 1if q >= 5:return Truefor 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 += 1elif row + i <= 14 and col + i <= 14 and self._board[row][col] == self._board[row + i][col + i]:q += 1else:q = 1if q >= 5:return Truefor 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 += 1elif row + i <= 14 and col - i >= 0 and self._board[row][col] == self._board[row + i][col - i]:q += 1else:q = 1if q >= 5:return Truedef move(self, row, col, is_black):if self._board[row][col] == EMPTY:self._board[row][col] = BLACK if is_black else WHITEreturn Truereturn Falsedef 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_colorpos = [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 = Truepygame.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 = Truewhile running:for event in pygame.event.get(): #捕获所有事件,鼠标|键盘if event.type == pygame.QUIT: # 捕获点击退出事件running = Falseelif 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_blackscreen.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 pygameclass Ball(object):def __init__(self, center, color, radius, speed):self._center = centerself._color = colorself._radius = radiusself._speed = speed@propertydef center(self):return self._center@propertydef radius(self):return self._radius@radius.setterdef radius(self, new):self._radius = newdef 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 = 0else:other.radius = int(math.sqrt(self._radius ** 2 + other.radius ** 2))self.radius = 0def 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 + syif x + self._radius >= 800:self._speed = -abs(sx), syelif x - self._radius <= 0:self._speed = abs(sx), syif 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 = Truewhile running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif 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, blueif __name__ == '__main__':main()

贪吃蛇(游戏)

from abc import ABCMeta, abstractmethod
from random import randint
import pygameFOOD_COLOR = (51, 221, 43)
WALL_COLOR = (255, 0, 0)
GREEN_COLOR = (0, 255, 0)
UP = 0
RIGHT = 1
DOWN = 2
LEFE = 3class GameObject(object, metaclass=ABCMeta):# 抽象类def __init__(self, x, y, color):self._color = colorself._x = xself._y = y@abstractmethod # 抽象方法,子类必须拥有此方法def draw(self, screen):pass@propertydef x(self):return self._x@propertydef y(self):return self._yclass Wall(GameObject):def __init__(self, x, y, width, height, color=WALL_COLOR):super().__init__(x, y, color)self._width = widthself._height = height@propertydef width(self):return self._width@propertydef height(self):return self._heightdef 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 = sizeself._show = Truedef 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._showclass SnakeNode(GameObject):# x, y 必须为基数(左上角坐标点),因为蛇移动的窗口的左上角坐标为(0,0)def __init__(self, x, y, size, color=GREEN_COLOR):super().__init__(x, y, color)self._size = size@propertydef size(self):return self._sizedef 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 = LEFEself._nodes = []# 装蛇的每个节点,利用append向后依次装载for index in range(10):node = SnakeNode(290 + index * 20, 250, 20)self._nodes.append(node)@propertydef dir(self):return self._dirdef change_dir(self, new_dir):"""改变蛇的方向:param new_dir: 新的方向:return: 返回新的方向,如果新方向是原来方向或者原来方向的反方向则不返回"""if (self._dir + new_dir) % 2 != 0:self._dir = new_dirdef move(self):head = self._nodes[0]snake_dir = self._dirx, y, size = head.x, head.y, head.sizeif snake_dir == UP:y -= sizeelif snake_dir == RIGHT:x += sizeelif snake_dir == DOWN:y += sizeelse:x -= sizenew_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.sizereturn 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.sizeif x == food.x and y == food.y:tail = self._nodes[-1]self._nodes.append(tail)return Truedef eat_me(self):"""判断蛇是否吃到自己:return: 吃到返回True"""head = self._nodes[0]x, y, size = head.x, head.y, head.sizefor a_node in self._nodes[4:]:ax, ay = a_node.x, a_node.yif abs(ax - x) < 20 and ay == y:return Trueif 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.keyif key == pygame.K_UP or key == pygame.K_w:new_dir = UPelif key == pygame.K_RIGHT or key == pygame.K_d:new_dir = RIGHTelif key == pygame.K_DOWN or key == pygame.K_s:new_dir = DOWNelif key == pygame.K_LEFT or key == pygame.K_a:new_dir = LEFEelif key == pygame.K_q:reset_game()return  # 加上return 让代码执行到此处后 后面的代码不在执行else:returnif new_dir != snake.dir:snake.change_dir(new_dir)def reset_game():"""重置游戏:return: 最初游戏状态(重新对蛇和食物赋值,并清空键盘事件(方向))"""nonlocal snake, foodsnake = 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 = Truei = 0while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif 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 += 1food.new_dot()screen.fill([244, 244, 244])display_str(i)pygame.quit()if __name__ == '__main__':main()

python基础 03相关推荐

  1. python基础03/字典

    python基础03/字典 内容大纲 1.字典 1.字典 字典是无序,可变的数据类型 字典:用于存储数据,储存大量数据,字典要比列表快 1.1 定义一个列表 lst1 = ["老大" ...

  2. python基础03——数据类型string

    1. 字符串介绍 在python中,引号中加了引号的字符都被认为是字符串. 1 name='jim' 2 address="beijing" 3 msg = '''My name ...

  3. Python基础03 序列

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! sequence 序列 sequence(序列)是一组有顺序的元素的集合 (严格的 ...

  4. python基础之---03基本语法

    python基础之---03基本语法 一:编码 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串. # -*- coding: utf-8 -*- 也 ...

  5. 【笔记】软件测试03——Python基础

    四.Python语言基础 一)基础概念 1.什么叫程序 程序即一段可以又计算机执行的代码. 2.程序的组成 程序=语法+算法+数据结构 语法是固定的,算法是解决问题的方法,算法是变化的. eg:如何从 ...

  6. Python 基础学习笔记 03

    Python基础系列 Python 基础学习笔记 01 Python 基础学习笔记 02 Python 基础学习笔记 03 Python 基础学习笔记 04 Python 基础学习笔记 05 文章目录 ...

  7. Python快速编程入门#学习笔记03# |第二章 :Python基础(代码格式、标识符关键字、变量和数据类型、数字类型以及运算符)

    全文目录 ==先导知识== 学习目标: 2.1 代码格式 2.1.1 注释 2.1.2 缩进 2.1.3 语句换行 2.2 标识符和关键字 2.2.1 标识符 2.2.2 关键字 2.3 变量和数据类 ...

  8. 万字长文爆肝Python基础入门【巨详细,一学就会】

    目录 数据的名字和种类--变量和类型 初探数据种类 数据类型 数值运算 比较运算 变量和赋值 变量的好处 用赋值更新变量 变量和数据类型的关系 总结 数据类型 数值运算 数值比较 变量和赋值 一串数据 ...

  9. python基础一入门必备知识-python基础教程#菜鸟也能看懂的超简单入门必备知识...

    python基础语法教程 python一直是一门非常火爆的编程语言,从简洁的语法,全面的功能,也是得到许多编程萌新的重视,在刚刚接触编程不久的人来说,python就像是代码编程的入门语言,但其实想成为 ...

最新文章

  1. Android使用ListView控件问题
  2. Windows Workflow Beta2 HOL学习笔记(三):使用IfElse Activity,声明条件和自定义活动...
  3. Linux CentOS 7下 Apache Tomcat 7 安装与配置
  4. Fiddler插件开发 - 实现网站离线浏览功能
  5. VC内存泄露检查工具:Visual Leak Detector
  6. Win 10 或可以运行安卓APP
  7. input中radio对象的使用、获取方法
  8. bootstrap-table 加表格线 样式换成table-bordered
  9. 用PHP编写提供性别的发法,第6节 Laravel-通过模型处理性别
  10. 解决IntelliJ IDEA在笔记本屏幕中部分界面显示不全被遮挡的问题
  11. python关系运算符实例_python编程中最常用的比较运算符实例
  12. 用金蝶kis记账王批量审核会计凭证的方法
  13. 设计模式六大原则-OCP
  14. 【水果识别】基于matlab GUI自助水果超市【含Matlab源码 594期】
  15. 如何同时分析顺心捷达多个已签收单号的物流信息
  16. eNSP交换机配置VLAN
  17. Excel画函数图像
  18. 小学计算机教师业务笔记,2016-2017学年度小学教师业务学习笔记
  19. 【每周一本书】之《大数据核心技术与实用算法》
  20. 常见图片文件格式简析

热门文章

  1. js nextSibling函数
  2. 一文教你读懂兴趣电商丨兴趣创造美好生活
  3. 生活是美好的,但仅属于懂得怎样生活的人
  4. SpringBoot打包修改jar名称
  5. Token认证模式详解
  6. Dagger学习 -- 基础概念
  7. Android 低功耗蓝牙开发简述
  8. 第十五篇:如何排查生产环境中的反压问题
  9. 教资综合素质计算机试题及答案,2019上全国教资统考中学综合素质试题及答案解析(3)...
  10. DataX之MySQL-overwrite-HIVE