首先课上总结:(看了其他视频的一个总结:)
第一部分,基础认知:
class People:
People便是一个大类,且开头要用大写
class People:
high =178
def eat(self):
tom = People()
tom.eat()
gugu = People()
gugu.eat()
high叫属性,在这类人这个大类下全都178.
tom叫做类对象,也就是人这个大类下,一类叫tom的人,tom这个类对象的地址和self地址相同。因此self作用其实就是引用tom这个人的一切做法。也就是引用方法,也就是tom.eat(),其中.eat就是方法,针对tom这个类对象这类人会做的方法。tom.eat = self.eat。同样,gugu.eat是gugu在吃,此时self等于gugu,即gugu.eat = self.eat.
总之哪个对象(tom。gugu)调用那种方法(eat),self就是这种对象行为的引用。
所以课后题:
5.请解释下边代码错误的原因:
>>> class MyClass:
name = 'Fishc'
def myFun(self):
print("Hello FishC!")
>>> MyClass.name
'Fishc'
>>> MyClass.myFun()
Traceback (most recent call last):
File "" , line 1, in <module>
MyClass.myFun()
TypeError: myFun() missing 1 required positional argument: 'self'
可以看到。在类下直接找类的属性是没有任何问题的,因为属性代表的就是类这个大类的特征。
而后面在大类下看行为,也就是.myFun()。这就需要具体到一个对象来进行这个行为,因此必须先定义一个人比如tom = Myclass(),也就是这大类下tom这个人做.myFun这个事情。所以改写为:
class MyClass:
name = 'Fishc'
def myFun(self):
print("Hello FishC!")
tom = MyClass()
tom.myFun()
第二部分:赋值属性
class People:
def __init__(self,name1):
self.name =name1
#self.属性 = 形参
def run (self):
print("%s在奔跑!"% self.name)
tom = People("Tom")
tom.run()
gugu =People("GuGu")
gugu.run()
首先,创建类函数会有两个步骤:1.开辟空间2.初始化值,因此初始化函数——init——是在引用类时自动开始得一个函数,不需要刻意去引用它
接着,赋值方法有很多种。比如以上例子改为外部赋值:
class People:
def run (self):
print("%s在奔跑!"% self.name)
tom = People()
tom.name = "tom"
#在这儿进行对name属性的赋值
tom.run()
由于tom = self的地址,因此self.name =‘tom’
但是这种方法容易受顺序限制
于是便有:
class People:
def __init__(self,name1):
self.name ='Tom'
def run (self):
print("%s在奔跑!"% self.name)
tom = People()
tom.run()
gugu =People()
gugu.run()
这种方法会在初始化给self定一个属性那么叫tom,但是存在的问题是tom也会给gugu,这并不是想要的
于是__init__有(self,形参1,形参2)
所以此时 定义self.属性 = 形参,便如最开始的例子。
定义一个类对象tom = People()时候。就可以将形参写入,这样形参就会到self.属性,不同的形参就可以对应不同的值
PS:另外内置方法:
del:会在最后一个行为做完后,内存清空前运行输出:若为全局变量,则不论运行顺序
0.按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。
平日票价100元
周末票价为平日的120%
儿童半票
class Ticket:
def __init__(self,child=False,weekend=False):
self.normal_price = 100
#固定的价格,可以当做不变的属性写上
if weekend:
self.weekend_price = 1.2
else:
self.weekend_price = 1
if child:
self.child_price =0.5
else:
self.child_price =1
def allprice(self,num):
return self.normal_price*self.weekend_price*self.child_price*num
#所有折扣乘数量等于最终总价折扣在乘原价总价
#学习这里利用初始化进行条件的判断,很实用
#非周末
human = Ticket()
Child = Ticket(child = True)
print('2大1小非周末价格为:%.2f'%(human.allprice(2)+Child.allprice(2)))
#周末
human = Ticket(weekend=True)
Child = Ticket(child = True,weekend=True)
print('2大1小周末价格为:%.2f'%(human.allprice(2)+Child.allprice(2)))
本题初始化值都没使用不固定的形参来对应价格,而是用来判断情况。而像一般价格这种固定值则可先写出来不论对象值都为100
1.游戏编程:按以下要求定义一个乌龟类和鱼类并尝试编写游戏。(初学者不一定可以完整实现,但请务必先自己动手,你会从中学到很多)
游戏场景为范围(x,y)为 0<=x<=10,0<=y<=10
游戏生成1只乌龟和10条鱼
它们的移动方向均随机
乌龟的最大移动能力为2(可以随机选择1还是2),鱼儿的最大移动能力为1
当移动到场景边缘,自动向反方向移动
乌龟初始化体力为100(上限)
乌龟每移动一次,体力消耗1
当乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20
鱼暂不计算体力
当乌龟体力值为0(挂掉)或鱼儿的数量为0游戏结束
import random as r
class Turtle:
def __init__(self):
#初始化数据
self.physical_strength = 100
#初始位置随机
self.x = r.randint(0,10)
self.y = r.randint(0,10)
def move(self):
#移动多少(用new_x代替是为了后面的判断后在赋值)
new_x = self.x + r.choice([-2,-1,1,2])#choice:随机返回元祖列表字符串任意元素
new_y = self.y + r.choice([-2,-1,1,2])
#判断是否出去
if new_x<0:
self.x = 0-(new_x)
elif new_x >10:
self.x = 20-(new_x)
else:
self.x = new_x
if new_y<0:
self.y = 0-(new_y)
elif new_y >10:
self.y = 20-(new_y)
else:
self.y = new_y
# 体力消耗
self.physical_strength -= 1
# 返回移动后的新位置
return (self.x, self.y)
#可以当做元组返回哟!
#加体力
def eat(self):
self.physical_strength += 20
if self.physical_strength >= 100:
self.physical_strength = 100
class Fish:
def __init__(self):
self.x = r.randint(0, 10)
self.y = r.randint(0, 10)
def move(self):
# 随机计算方向并移动到新的位置(x, y)
new_x = self.x + r.choice([1, -1])
new_y = self.y + r.choice([1, -1])
# 检查移动后是否超出场景x轴边界
if new_x < 0:
self.x = 0 - new_x
elif new_x > 10:
self.x = 10 - (new_x - 10)
else:
self.x = new_x
# 检查移动后是否超出场景y轴边界
if new_y < 0:
self.y = 0 - new_y
elif new_y > 10:
self.y = 10 - (new_y - 10)
else:
self.y = new_y
# 返回移动后的新位置
return (self.x, self.y)
#测试
#注意开始时候是全部和类对其!
turtle = Turtle()
fish = []
#用列表和for循环进行鱼增加操作,每1次就会有一组初始化数据保存进列表中
for i in range(10):
new_fish = Fish()
fish.append(new_fish)
#开始游戏不停
while True:
#首先写停止游戏条件。鱼没了,龟死了
if not len(fish):
print('鱼没了,游戏结束!')
break
if not turtle.physical_strength:
#注意,你调用的是一个变量,而不是函数,不要加括号!!!!!!!!
print('龟死了,游戏结束!')
break
#游戏开始
print('龟的坐标是:',(turtle.x,turtle.y))
***#坐标用文字+元祖的模式输出***
turtle.move()
print('龟现在的坐标是:',(turtle.x,turtle.y))
for each in fish:
#相当于each = Fish(),所以后面坐标全部用each.x
#这就是在类里面用for循环的妙处,直接元素可以进去初始化得到一个初始化坐标数据,而且每次由于初始化里面ran函数会不一样
print('鱼的坐标是:',(each.x,each.y))
each.move()
print('鱼现在的坐标是:',(each.x,each.y))
if turtle.x == each.x and turtle.y == each.y:
#不能直接比较元组,除非用cmp,不然会比较首个坐标,所以单个元素
#用remove直接去元素比较好
turtle.eat()
fish.remove(each)
print('死了一只小鱼,龟体力增加20')
1.一定注意调用变量无括号,调用函数有,for循环列表inlist不用加括号
2.self.xxx 是可以任意加减的,只要其值为int型
3.每个函数要么print,要么必须有个返回值,且返回值不能为等式,可以返回元祖内型,则为一个坐标等
4.在类里面用for循环的妙处,直接元素可以进去初始化得到一个初始化坐标数据,而且每次由于初始化里面ran函数会不一样
5.在一个游戏制作中。首先是对不同分类,且不同条件下的属性方法进行定义,然后开始对类进行变量赋值,注意此时与类的定义是在同列,不然不找不到类的定义,游戏开始后(whlie True),则先写游戏终止条件,在写游戏开始得顺序,这个逻辑比较好
6.字符串,元祖拼接是可行的