- 面向对象入门
- 一款简单自动运行的小游戏模拟;在一维的地图上,有一只虫子和一直蚂蚁。每一次他们都走过一个-3,-2,2,3个随机单位的举例(选定走法,若达到地图边界则放弃移动)。当蚂蚁和虫子处于同一个位置的时候蚂蚁吃掉虫子,游戏结束
- PO(面向过程):虫子的初始位置,蚂蚁的初始位置,进入循环,按照规则,蚂蚁和虫子移动位置,直到蚂蚁虫子在同一位置游戏结束
#coding=gbk import random ant_point=random.randint(0,20)#位置初始化 worm_point=random.randint(0,20) print('ant_point:',ant_point,'worm_point:',worm_point)#打印初始位置 step=[-2,+2,-3,+3]#只能移动的步数 while ant_point!=worm_point: astep=random.choice(step)#调用函数随机选择移动的步数 if 0<ant_point+astep<=20: ant_point+=astep astep=random.choice(step) if 0<worm_point+astep<=20: worm_point+=astep print('ant_point:',ant_point,'worm_point:',worm_point)#打印走动之后的位置
- OO(面向对象):对象:地图,虫子,蚂蚁;地图是唯一的只需要记录蚂蚁虫子的位置;蚂蚁和虫子直到自己的位置;蚂蚁虫子按规则移动;定义蚂蚁虫子地图三个类;主程序中实例化
#coding=gbk import random class Sprite: step=[-2,2,-3,3] def __init__(self,gm,point=None):#默认构造参数 self.gm=gm if point is None: self.point=random.randint(0,20) else: self.point=point def jump(self): astep=random.choice(Sprite.step) if 0 <= self.point + astep<= 20: self.point+=astep class Ant(Sprite): def __init__(self,gm,point=None): super().__init__(gm, point) self.gm.set_point('ant',self.point) def jump(self): super().jump() self.gm.set_point('ant',self.point) class Worm(Sprite): def __init__(self,gm,point=None): super().__init__(gm, point) self.gm.set_point('worm',self.point) def jump(self): super().jump() self.gm.set_point('worm',self.point) class gamemap: def __init__(self): self.ant_point=None self.worm_point=None def catched(self): print('ant:',self.ant_point,'worm :',self.worm_point) if self.ant_point is not None and self.worm_point is not None and self.ant_point==self.worm_point: return True def set_point(self,src,point): if src=='ant': self.ant_point=point if src=='worm': self.worm_point=point if __name__=='__main__': gm=gamemap() worm=Worm(gm) ant=Ant(gm) while not gm.catched(): worm.jump() ant.jump()
- PO(面向过程):虫子的初始位置,蚂蚁的初始位置,进入循环,按照规则,蚂蚁和虫子移动位置,直到蚂蚁虫子在同一位置游戏结束
- 简单的类
-
#coding=gbk class TestClass:#定义一个空类 pass tc=TestClass()#类的实例化 print(tc) class TestClass_a: def db(self): self.height=20 print(self.height) tc=TestClass_a() print(tc)#打印出了类的地址 #类的说明 查看方式 类名.__doc__或者help(类名) class tss: ''' #类的说明是在类名下面用''' ''' 包围起来的内容 这是一个类的说明 ''' pass print(tss.__doc__) #打印类的说明 print(help(tss)) #新式类和经典类 #①python3.x版本中都是新式类,不用继承Object #②python2.x版本中都是经典类,继承object为新式类 #③区别:经典类为深度优先,新式类为广度优先
-
- 类的属性
- 私有属性
- 单下划线
#私有属性:使用__(双下划线)开头的变量名加以标志,只有类对象自己能访问;使用_(单下划线)开头的变量名加以标识,只有类对象和其子类能够访问 class A: def __init__(self): self._ab=0 #__ab表示的是私有属性 ,python对__ab进行名称修改,在外部无法看见 def info(self): print(self._ab) a=A() a.info() a._ab=3 #私有属性在类的外部不能对他修改 创建了一个新的实例化属性 a.info() #单下划线开头的私有属性在外部可以访问,可以进行属性值的修改 print(a._ab)
- 双下滑线
-
#私有属性:使用__(双下划线)开头的变量名加以标志,只有类对象自己能访问;使用_(单下划线)开头的变量名加以标识,只有类对象和其子类能够访问 class A: def __init__(self): self.__ab=0 #__ab表示的是私有属性 ,python对__ab进行名称修改,在外部无法看见 def info(self): print(self.__ab) a=A() a.info() a.__ab=3 #私有属性在类的外部不能对他修改 创建了一个新的实例化属性 a.info() print(a.__ab)
- 单下划线
- 实例化属性
-
#coding=gbk class testcss: cssa='class-attribe' #定义类属性 不同类实例中类属性都是一样的 #一般不建议在__init__方法之外去创建和初始化实例属性 #一般也不建议在类外定义和修改实例属性,修改可以定义单独的方法进行修改 def __init__(self): self.a=0 #a,b都是实例属性 self.b=0 def info(self): print('a is :'+str(self.a),'b is ;',self.b,'cssa is :',self.cssa) if __name__=='__main__': tc=testcss() tcc=testcss() tc.info() tcc.info() testcss.cssa='woshileishuxing' tc.info() tcc.info() tc.color='red' #在类外定义实例属性 print(tc.color)
- __doc__ __name__ __dict__ __module__ __base__ 这些特殊属性
- 类的能动性(方法)
-
#coding=gbk #类的方法调用 #在内部调用:self.方法名.参数列表 在外部调用 对象名.方法名.参数列表 class washer: def __init__(self,water=10,scout=2):#构造方法名称是不变的, 默认参数值 self.water=water self.scout=scout def set_water(self,water): self.water=water def set_scout(self,scout): self.scout=scout def add_water(self,): print('add water :',self.water) # self.water=water def add_scout(self,): # self.scout=scout print('add scout :',self.scout) def start_wash(self): self.add_scout() self.add_water() print('start wash...') if __name__=='__main__': a=washer() a.start_wash()#默认构造函数产生 b=washer(100,8)#自主构造产生 b.start_wash()
- 私有属性
- 深入类的属性
- 同名的类属性和实例属性
-
#coding=gbk #一个类中存在同名的类属性:①当以实例名.属性名引用时,优先引用实例属性;②以类名.属性名引用时,只能引用类属性 # class A: # a=0 # def __init__(self): # self.a=1 # self.b=1 # a=A() # print(a.a) # print(a.b) # print(A.a) # # print(A.b)#不存在类属性b,报错 # # #反射 hasattr(obj_bame,'属性名')测试是否有这个属性名 setattr(obj-name,'属性名',值) 设置属性值 getattr(obj_name,'属性名') 得到属性值 # print(getattr(a, 'a')) # print(setattr(a, 'a', 20)) # print(a.a) # print(hasattr(a, 'a')) #属性包装--将方法包装成属性,以隐藏相关实现 #可读:@property 可写:@<property-name>.setter 可删:@<property-name>.deleter
-
- 属性的包装
-
#coding=gbk #属性包装--将方法包装成属性,以隐藏相关实现,我们可以通过将方法包装成一个属性,然后通过调用这个属性相当于调用这个方法 #可读:@property 可写:@<property-name>.setter 可删:@<property-name>.deleter class washer: def __init__(self,water=10,scout=2):#构造方法名称是不变的, 默认参数值 self._water=water self.scout=scout self.year=2010 #将water方法变成了属性,可以读取的属性 #属性包装,使用实例.属性名调用可以去使用这种方式写 @property def water(self): return self._water #将方法变成属性,可以修改的属性 @water.setter def water(self,water): if 0<water<=500: self._water=water else : print('set water wrong,water is low') @property def total_year(self): return 2015-self.year def set_water(self,water): self.water=water def set_scout(self,scout): self.scout=scout def add_water(self,): print('add water :',self.water) # self.water=water def add_scout(self,): # self.scout=scout print('add scout :',self.scout) def start_wash(self): self.add_scout() self.add_water() print('start wash...') if __name__=='__main__': w=washer() print(w.water) w.water=123 print(w.water) print(w.total_year)
- 描述符
-
#coding=gbk #描述符:将实现特殊协议方法的类作为另一个类的类属性,用来拦截和控制属性访问并且可以重复使用 # 协议方法:__get__() # __set__() # __delete__() #以上三种协议都实现的:数据描述符 #部分实现的称为非数据描述符,所有的类成员函数都是非数据描述符(都可能实现一个或多个协议方法) class NonNeg: #协议方法 def __init__(self,default=0): self.default = default #这三种协议配套使用 def __get__(self,instance,owner): return self.default def __set__(self,instance,val): if val > 0: self.default = val else: print("The value must be NonNegative!") def __delete__(self,instance): pass class Movie: rating = NonNeg() score = NonNeg() if __name__ == '__main__': m = Movie() print('rating:',m.rating) print('score:',m.score) m.rating = 80 print('rating:',m.rating) m.score = -3 print('score:',m.score)
- __call__()让类的实例和函数一样可以调用
-
>>> class tst: def __call__(self): print('call') >>> t=tst() >>> t() call >>>
-
- 同名的类属性和实例属性
- 类方法和静态方法
- 静态方法
- ①用 staticmethod装饰器装饰 ②参数不用self ③不能引用或者访问实例属性 ④可以通过 类.类变量 访问类属性 ⑤可以用类或者类实例来调用静态法
- 类方法
- ①装饰器@classmethod 必须提供参数cls(这个参数可以是类名)②不能引用或者访问实例属性(因为实例属性在没有实例化之前是不存在的)③可以用类实例,类调用
-
#coding=gbk class Washer: company = "Le Xi" #类属性 def __init__(self,water=10,scour=2): self._water = water self.scour = scour self.year = 2010 @staticmethod #静态方法的装饰器 def spins_ml(spins): #静态方法可以没有参数,一定没有self参数 # print("company:",Washer.company) 调用类.类属性可以 # print('year:',self.year) 静态方法中不能引用实例属性 return spins * 0.4 @classmethod #类方法装饰器 必须提供参数cls, def get_washer(cls,water,scour): #这里的cls可以换成类名字 print("company:",Washer.company) #不能引用或者访问实例属性 # print('year:',self.year) return cls(water,cls.spins_ml(scour)) @property def water(self): return self._water @water.setter def water(self,water): if 0 < water <=500: self._water = water else: print("set Failure!") @property def total_year(self): return 2015 - self.year def set_water(self,water): self.water = water def set_scour(self,scour): self.scour = scour def add_water(self): print('Add water:',self.water) def add_scour(self): print('Add scour:',self.scour) def start_wash(self): self.add_water() self.add_scour() print('Start wash...') if __name__ == '__main__': # print(Washer.spins_ml(8)) 通过类.类方法调用静态方法 # w = Washer() 用类的实例调用静态方法 # print(w.spins_ml(8)) # w = Washer(200,Washer.spins_ml(9)) 在实例化的手去调用静态方法 # w.start_wash() w = Washer.get_washer(100,9) #类调用类方法 w.start_wash()
- 静态方法
- 类继承
- 类继承方式
-
>>> class A: pass >>> A.__base__ 类A的父类:默认为Object <class 'object'> >>> class B(A): B继承A pass >>> B.__base__ <class '__main__.A'> >>> class C: pass >>> class D(A,C): D继承A,C pass D.__bases__ (<class '__main__.A'>, <class '__main__.C'>)
- 单继承
-
1 #coding=gbk 2 class Washer: 3 company = "Le Xi" 4 def __init__(self,water=10,scour=2): 5 self._water = water 6 self.scour = scour 7 8 @staticmethod 9 def spins_ml(spins): 10 return spins * 0.4 11 12 @classmethod 13 def get_washer(cls,water,scour): 14 return cls(water,cls.spins_ml(scour)) 15 16 @property 17 def water(self): 18 return self._water 19 20 @water.setter 21 def water(self,water): 22 if 0 < water <=500: 23 self._water = water 24 else: 25 print("set Failure!") 26 27 def set_scour(self,scour): 28 self.scour = scour 29 30 def add_water(self): 31 print('Add water:',self.water) 32 33 def add_scour(self): 34 print('Add scour:',self.scour) 35 36 def start_wash(self): 37 self.add_water() 38 self.add_scour() 39 print('Start wash...') 40 41 class washerdry(Washer): #继承类 42 43 #这是单继承先是在子类中寻找方法,找不到再依次向上查找方法。 44 #在多重继承的时候,查找方法会采用广度优先的查找方式进行查找 45 def dry(self): 46 print('dry clothes...') 47 48 def start_wash(self):#重载父类的方法 49 print('...') 50 super().start_wash()#在子类中调用父类的方法 51 print('...') 52 53 if __name__=='__main__': 54 w=washerdry() 55 w.start_wash() 56 print(w.scour,w.company) 57 w.dry()
- 多重继承:查找调用函数的方式,广度优先的方式,从最近的开始进行查找调用
-
>>> class A: def foo(self): print('aaa') >>> class B: def foo(self): print('B bbb') >>> class C(A,B): pass >>> c=C() >>> c.foo() aaa >>> class D(B,A): pass >>> D().foo() B bbb >>>
- 类的特殊方法
- 深入理解类
-
>>> class Empty: pass >>> ept=Empty 类和一个变量进行绑定 >>> ept() <__main__.Empty object at 0x0000023235576320> >>> ept.foo='foo' 为类增加属性 >>> ept.foo 'foo' >>> def use_class(mc): 把类作为函数的参数传递 return mc() >>> use_class(Empty) 类作为一个对象 <__main__.Empty object at 0x0000023235569940> >>>
- 元类:类的创建者和管理者,所有的类都是元类的实例
-
>>> class A: pass #通过isinstance方法可以得出每个类都是元类的实例 >>> isinstance(A,type) True
类的实例化过程
#coding=gbk #实例化时:先调用__new__()方法,返回类的实例,然后再调用__init__方法进行初始化 class Custom: def __init__(self): print('init method.') def __new__(cls,*args,**kwargs): print('new instance.') return object.__new__(cls,*args,**kwargs) if __name__=='__main__': Custom();
#coding=gbk #定义自定义元类 #步骤;继承type类,新建__new__(),调用__init__()方法 class MyMeta(type): def __init__(self,name,bases,dicts):#为每一个使用该类的类添加一个方法和属性 print('Init Instance.') #为字典添加键的方式来为使用这个元类的类创建一个方法 def __new__(cls,name,bases,dicts): dicts['info'] = lambda self:print('Djx.')#匿名函数lambda res = type.__new__(cls,name,bases,dicts)#用type创建类 res.company = 'MaiZi'#外部添加一个类属性 return res#返回类 class custom(metaclass=MyMeta): pass if __name__ == '__main__': cus = custom() cus.info() print(cus.company) class cus: __metaclass__ = MyMeta pass __metaclass__ = MyMeta
类的一些方法
#coding=gbk #构造序列 class myseq: def __init__(self): self.lseq=['I','II','III','IIII'] def __len__(self): return len(self.lseq) def __getitem__(self,key): if 0 < key < 4: return self.lseq[key] if __name__=='__main__': m=myseq() for i in range(4): print(m[i]) #构造迭代器 class myiter: def __init__(self,start,end): self.count=start self.end=end def __iter__(self): return self def __next__(self): if self.count < self.end: r=self.count self.count+=1 return r else: raise StopIteration if __name__=='__main__': for i in myiter(1,10): print(i) #构造可比较类 class Point: def __init__(self,x,y): self.x = x self.y = y def __lt__(self,oth): return self.x < oth.x def __gt__(self,oth): return self.y > oth.y if __name__ == '__main__': pa = Point(0,1) pb = Point(1,0) print(pa < pb) print(pa > pb)
- 鸭子类型
- 多态:一种类型具有多种类型的能力,允许不同的对象对同一消息做出灵活的反应,以一种通用的方式对待可使用的对象,非动态语言必须通过继承和接口实现
- 通过继承实现多态,子类通过重载父类的方法实现多态
-
#对于继承了同一个类的子类,当父类可以在函数中最为参数调用时,子类也是同样可以的,这就是通过继承实现多态 >>> class animal: def move(self): print('aaa') >>> class dog(animal): pass >>> def move(obj): obj.move() >>> a=animal() >>> move(a) aaa >>> d=dog() >>> move(d) aaa
通过重载父类的方法实现多态>>> class cat(animal):
def move(self):
print('aaaaaaa')
>>> class sheep(animal):
def move(self):
print('aaaa')
>>> move(sheep())
aaaa
>>> move(cat())
aaaaaaa
-
- 动态类型语言与鸭子类型::变量绑定的类型具有不确定性,函数和方法可以接受任何类型的单数,调用方式是不检查提供的参数类型,调用是否成功由参数的方法和属性确定
-
#coding=gbk class Point: def __init__(self,x,y): self.x = x self.y = y def __add__(self,oth): return Point(self.x + oth.x , self.y + oth.y) def info(self): print(self.x,self.y) # class D3Point(Point): # def __init__(self,x,y,z): # super().__init__(x,y) # self.z = z # def __add__(self,oth): # return D3Point(self.x + oth.x , self.y + oth.y , self.z + oth.z) # def info(self): # print(self.x,self.y,self.z) class D3Point:#动态类型绑定:鸭子动态 def __init__(self,x,y,z): self.x = x self.y = y self.z = z def __add__(self,oth): return D3Point(self.x + oth.x , self.y + oth.y , self.z + oth.z) def info(self): print(self.x,self.y,self.z) def myadd(a,b):#只要函数的类型可以调用a+b功能,就能传递参数实例 return a + b if __name__ == '__main__': myadd(Point(1,2),Point(3,4)).info() myadd(D3Point(1,2,3),D3Point(4,5,6)).info()
设计模式:用来提高代码复用和可维护性的方式,很好的指导软件设计过程,是成功的软件设计模式和体系结构,用于解决特定类型的问题的面向对象编程模型
- python与设计模式
- 有的模式已经在语言中内置了,比如迭代器模式;单例模式可以直接用模块级变量来实现;普通工厂模式可以直接通过传入类名作为参数实现
- 单例设计
-
#coding=gbk #普通的单例设计模式 # class singleclass: # def __init__(self,x=0): # self.x=0 # # sc=singleclass() #模块级变量sc,在其他的程序中使用sc,无论什么时候使用,都是指向singleclass这个单一的实例对象 # # def tsc(): # print(sc.x) # sc.x=10 # print(sc.x) # # # def tsc_2(): # print(sc.x) # sc.x=9 # print(sc.x) # # if __name__=='__main__': # tsc() # tsc_2() #通过修改类的父类的__new__()方法来实现单例模式 class singleton: def __new__(cls,*args,**kwargs): if not hasattr(cls,'_sgl'): #用类的类属性指定一个类的单实例 ,测试这个类是否有一个类属性 cls._sgl=super().__new__(cls,*args,**kwargs) #调用父类的new方法来实例化一个类,赋值给类属性cls。sgl return cls._sgl if __name__=='__main__': sa=singleton() sb=singleton() print(id(sa))#两个类的实例化是一个单一的实例 print(id(sb))
- 工厂模式
-
#coding=gbk class ab: a=3 class ac: a=0 class myfactory: #建立工厂类 def get_instance(self,ins): return ins()#对这个变量代表的类进行实例化 if __name__=='__main__': mf=myfactory() print(type(mf.get_instance(ab))) print(type(mf.get_instance(ac)))
- 策略模式:让一个对象的某个方法可以随时改变。不用更改对象代码;对于动态类型的python不需要定义接口,基本的实现方法:用类作为参数传递;最简单的实现方法:函数最为参数传递
-
#coding=gbk class moveable: def move(self): print('move...') class moveonfeet(moveable): def move(self): print('feet move...') class moveonwheels(moveable): def move(self): print('move on wheels move,,,') class moveobj: def set_move(self,moveable):#通过set——move修改move方法 self.moveable=moveable()#实例化 def move(self): self.moveable.move() if __name__=='__main__': m=moveobj() m.set_move(moveable) m.move() m.set_move(moveonfeet) m.move() m.set_move(moveonwheels) m.move()
-
#coding=gbk def movea(): print('a moveing...') def moveb(): print('b moving...') #传递的参数是一个函数 class moveobj: def set_move(self,moveable):#动态类型邦迪 self.moveable=moveable #函数不需要实例化 def move(self): self.moveable() if __name__=='__main__': m=moveobj() m.set_move(movea) m.move() m.set_move(moveb) m.move() m.set_move(moveb) m.move()
- 设计模式2
- 装饰模式:通过继承可以获得父类的属性,可以通过重载修改其方法;装饰模式可以不以继承的方式而动态的修改类的方法;装饰模式可以不以继承的方式而返回一个呗修改的类
-
#coding=gbk class BeDeco:#装饰类 def be_edit_fun(self): print('Source fun.') def be_keep_fun(self): print('Keep fun.') class Decorater:#装饰类 def __init__(self,dec):#传入修改的类的名称 self._dec = dec()#实例化传入类 def be_edit_fun(self):#定义和被装饰类的同样的方法 print('Start...') self._dec.be_edit_fun()#修改的方法 def be_keep_fun(self): self._dec.be_keep_fun()#保留的方法 if __name__ == '__main__': bd = BeDeco() bd.be_edit_fun() bd.be_keep_fun() dr = Decorater(BeDeco)#传入被修饰的类 dr.be_edit_fun() dr.be_keep_fun()
-
#coding=gbk class Water: def __init__(self): self.name = 'Water' def show(self): print(self.name) class Deco: #要被装饰类 def show(self): print(self.name) class Sugar(Deco): def __init__(self,water): self.name = 'Sugar' self.water = water def show(self): print(self.name) print(self.water.name) class Salt(Deco): def __init__(self,water): self.name = 'Salt' self.water = water def show(self): print(self.name) print(self.water.name) if __name__ == '__main__': w = Water() s = Sugar(w)#利用sugar装饰了water s.show() s = Salt(w)#利用salt装饰了water s.show()
-
#coding=gbk def deco(a_class): #类装饰器 class NewClass: def __init__(self,age,color): self.wrapped = a_class(age) self.color = color def display(self): print(self.color) print(self.wrapped.age) return NewClass @deco #装饰器语法 将cat类传入上述deco函数,包装完以后返回新的包装的类 class Cat: def __init__(self,age): self.age = age def display(self): print(self.age) if __name__ == '__main__': c = Cat(12,'black') c. display()
- 通过组合来构建复杂的对象
- 组合:零件:基础类;机器:包含其他类的类。组合:零件+机器;体现自下而上的编程方法
- 组合案例--雪人:
-
#coding=gbk class Shape:#shape 不带角度的基类 def __init__(self,cvns,points):#cvns 绘制图形的画布参数 points坐标参数 self.cvns = cvns self.points = points self.pid = None #在画布当中的id号 def delete(self): #将当前的图形删除 if self.pid: self.cvns.delete(self.pid) class ShapeAngles(Shape):#带角度的基类 def __init__(self,cvns,points,angles=(10,170)):#angles 是角度 图形角度 super().__init__(cvns,points) self.angles = {'start':angles[0],'extent':angles[1]} class HatTop(Shape):#无角度类 def draw(self):#绘制函数 self.pid = self.cvns.create_oval(*self.points)#绘制圆形的方法,返回id class HatBottom(Shape): def draw(self): self.pid = self.cvns.create_polygon(*self.points) class Hat:#帽子组合类 def __init__(self,cvns,start_point,w,h): self.cvns = cvns self.start_point = start_point self.w = w self.h = h self.ht = HatTop(self.cvns,self.ht_cacu())#实例化帽子顶部 self.hb = HatBottom(self.cvns,self.hb_cacu())#实例化帽子底部 def draw(self): self.ht.draw() self.hb.draw() def delete(self): self.ht.delete() self.hb.delete() def ht_cacu(self):#计算位置 r = self.h / 3 / 2 x1 = self.start_point[0] + self.w /2 - r y1 = self.start_point[1] x2 = x1 + 2 * r y2 = y1 + 2 * r return x1,y1,x2,y2 def hb_cacu(self): x1 = self.start_point[0] + self.w / 2 y1 = self.start_point[1] + self.h / 3 x2 = self.start_point[0] + self.w / 3 y2 = self.start_point[1] + self.h x3 = self.start_point[0] + self.w / 3 * 2 y3 = y2 return x1,y1,x2,y2,x3,y3 class Sense(ShapeAngles): def draw(self): self.pid = self.cvns.create_arc(*self.points,**self.angles)#绘制一条弧线 class Face(HatTop):#圆和帽子顶部类似 pass class Head: def __init__(self,cvns,start_point,w,h): self.cvns = cvns self.start_point = start_point self.w = w self.h = h eye0_points = self.eye0_cacu() dx = self.h / 3 + self.h / 9 eye1_points = (eye0_points[0] + dx,eye0_points[1], eye0_points[2] + dx,eye0_points[3]) self.face = Face(self.cvns,self.face_cacu()) self.eye0 = Sense(self.cvns,eye0_points) self.eye1 = Sense(self.cvns,eye1_points) self.mouth = Sense(self.cvns,self.mouth_cacu(),(-10,-170)) def draw(self): self.face.draw() self.eye0.draw() self.eye1.draw() self.mouth.draw() def face_cacu(self): x1 = self.start_point[0] + (self.w - self.h) / 2 y1 = self.start_point[1] x2 = x1 + self.h y2 = y1 + self.h return x1,y1,x2,y2 def eye0_cacu(self): left_point = (self.start_point[0] + (self.w - self.h) / 2,self.start_point[1]) x1 = left_point[0] + self.h / 6 y1 = left_point[1] + self.h / 3 x2 = x1 + self.h / 3 y2 = left_point[1] + self.h / 2 return x1,y1,x2,y2 def mouth_cacu(self): left_point = (self.start_point[0] + (self.w - self.h) / 2,self.start_point[1]) x1 = left_point[0] + self.h / 3 y1 = left_point[1] + 2 * self.h / 3 x2 = x1 + self.h / 3 y2 = y1 + self.h / 3 / 2 return x1,y1,x2,y2 class BodyOutline(HatTop):#圆 pass class Button(HatTop):#圆 pass class Body: def __init__(self,cvns,start_point,w,h): self.cvns = cvns self.start_point = start_point self.w = w self.h = h self._button_size = 10 self.buttons = [] self.bo = BodyOutline(self.cvns,self.body_cacu()) for pnts in self.all_button_points(): self.buttons.append(Button(self.cvns,pnts)) def draw(self): self.bo.draw() for bttn in self.buttons: bttn.draw() def body_cacu(self): x1,y1 = self.start_point x2 = x1 + self.w y2 = y1 + self.h return x1,y1,x2,y2 def button0_cacu(self): x1 = self.start_point[0] + self.w / 2 - self._button_size y1 = self.start_point[1] + self.h / 5 - self._button_size x2 = x1 + 2 * self._button_size y2 = y1 + 2 * self._button_size return x1,y1,x2,y2 def move_dy(self,points,size): y1 = points[1] + size y2 = points[3] + size return points[0],y1,points[2],y2 def all_button_points(self): b0_points = self.button0_cacu() size = self.h / 5 points = [] for i in range(4): points.append(self.move_dy(b0_points,i * size)) return points def set_button_size(self,size): self._button_size = size class Snow: def __init__(self,cvns,points,w=150,h=450): self.cvns = cvns self.points = points self.w = w self.h = h self.hat = Hat(self.cvns,self.points,self.w,self.h / 6) self.head = Head(self.cvns,(self.points[0],self.points[1] + self.h / 6),self.w,self.h / 3) self.body = Body(self.cvns,(self.points[0],self.points[1] + self.h / 2),self.w,self.h / 2) def draw(self): self.hat.draw() self.head.draw() self.body.draw() if __name__ == '__main__': import tkinter root = tkinter.Tk() cvns = tkinter.Canvas(root,width=600,height=665,bg='white') cvns.pack() snow = Snow(cvns,(10,5),300,660) snow = snow.draw() root.mainloop()
- 一款简单自动运行的小游戏模拟;在一维的地图上,有一只虫子和一直蚂蚁。每一次他们都走过一个-3,-2,2,3个随机单位的举例(选定走法,若达到地图边界则放弃移动)。当蚂蚁和虫子处于同一个位置的时候蚂蚁吃掉虫子,游戏结束