练习:乌龟吃小鱼,乌龟的体力值为100.每移动一步消耗一点体力。它可以选择移动一部还是两步,鱼每次只能移动一步,方向任意。当乌龟的位置与小鱼的位置相同时,小鱼被乌龟吃掉,当10条小鱼全部被吃掉或者乌龟体力耗尽时游戏结束。
import random as r
legal_x = [0,10]
legal_y = [0,10]
class Turtle:
def __init__(self):
self.power = 100
self.x = r.randint(legal_x[0],legal_x[1])
self.y = r.randint(legal_y[0],legal_y[1])
def move(self):
new_x = self.x + r.choice([1,2,-1,-2])
new_y = self.y + r.choice([1,2,-1,-2])
if new_x < legal_x[0]:
self.x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
self.x = legal_x[1] - (new_x - legal_x[1])
else:
self.x = new_x
if new_y < legal_y[0]:
self.y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
self.y = legal_y[1] - (new_y - legal_y[1])
else:
self.y = new_y
self.power -= 1
return(self.x,self.y)
def eat(self):
self.power += 20
if self.power > 100:
self.power = 100
class Fish:
def __init__(self):
self.power = 100
self.x = r.randint(legal_x[0],legal_x[1])
self.y = r.randint(legal_y[0],legal_y[1])
def move(self):
new_x = self.x + r.choice([1,-1])
new_y = self.y + r.choice([1,-1])
if new_x < legal_x[0]:
self.x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
self.x = legal_x[1] - (new_x - legal_x[1])
else:
self.x = new_x
if new_y < legal_y[0]:
self.y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
self.y = legal_y[1] - (new_y - legal_y[1])
else:
self.y = new_y
self.power -= 1
return(self.x,self.y)
turtle = Turtle()
fish = []
for i in range(10):
new_fish = Fish()
fish.append(new_fish)
while True:
if not len(fish):
print('鱼吃完了游戏结束')
break
if not turtle.power:
print('乌龟体力耗尽,游戏结束')
break
pos = turtle.move()
for each_fish in fish[:]:
if each_fish.move() == pos:
turtle.eat()
fish.remove(each_fish)
print('有一条鱼儿被吃完了')
运行:
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
有一条鱼儿被吃完了
乌龟体力耗尽,游戏结束
>>>
一、组合
将没有很大关联的类别混搭在一起,把旧类放到新类里,不用继承
1、基本语法
class Shark():
def __init__(self,x):
self.num = x
class Fish():
def __init__(self,y):
self.num = y
class Pool():
def __init__(self,x,y):
self.shark = Shark(x) #这里用到的就是组合
self.fish = Fish(y)
print('这里一共有%s只鲨鱼,%s条鱼' % (self.shark.num,self.fish.num))
>>> p = Pool(12,13)
这里一共有12只鲨鱼,13条鱼
2、如果方法和属性名相同,属性会覆盖方法。
3、了解 多继承 Mix-in,动态改变类的基类。
注意:
__bases__
是一个tuple,所以增加一个值要使用tuple类型,而单个元素tuple的写法为(foobase,)
类必须先存在。所以,如果想使用这一技术,先要将相关的类的模块导入(import)。
二、类、类对象和实例对象
一切类都是对象
类对象,抽象,如水果
实例对象,具体,如桃子
在定义的时候就是类
写完之后就成了类对象
类属性和类对象是绑定的,不会因为实例属性的变化而改变
三、绑定,需要有实例才能被调用,用self接受绑定
类被删除了,属性在关闭之前仍可以使用
四、相关的BIF
1、issubclass(class,classinfo)
如果class是classinfo的子类则返回true class可以是一个元组,同时自身会被认为是自身的子类
class a:
pass
class b(a):
pass
运行:
>>> issubclass(a,b)
False
>>> issubclass(b,a)
True
>>> issubclass(b,b)
True
>>> issubclass(a,object) #类定义的默认就是object
True
>>>
2isinstance(object,classinfo)
判断实例化对象是不是属于这种类型
class a:
pass
class b(a):
pass
运行:
>>> c = a()
>>> isinstance(c,a)
True
3、hasattr(object,’name‘)
,测试对象object是否有指定的属性name getattr(object,name[,default])
,可选参数,如果指定的参数存在则返回打印,如果不存在则返回默认的对象defult
setattr(object,name,value)
,同理
class C():
def __init__(self):
self.x = 'A'
运行:
>>> c = C()
>>> getattr(c,'x','没有这个属性') #获取实例对象c中指定属性x,如果有则输出x的值
'A'
>>> getattr(c,'b','没有这个属性') #如果没有则输出默认的‘没有这个属性’
'没有这个属性'
4、property()
,将所有属性给某个名字。 提供名字给用户,在需要修改的时候直接改属性,通过函数将名字和属性直接挂钩,相应的用户的也产生了变化。
class C():
def __init__(self,size = 10):
self.size = size
def getsize(self):
return self.size
def setsize(self,value):
self.size = value
def delsize(self):
del self.size
x = property(getsize,setsize,delsize)
运行:
>>> c = C()
>>> c.x = 3 #x与size直接挂钩
>>> c.x
3
>>> c.size
3