zoukankan      html  css  js  c++  java
  • Python--面向对象编程

    • 面向对象入门
      •   一款简单自动运行的小游戏模拟;在一维的地图上,有一只虫子和一直蚂蚁。每一次他们都走过一个-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()
                  
      •   简单的类
        • #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()
          View Code
        • 多重继承:查找调用函数的方式,广度优先的方式,从最近的开始进行查找调用
        • >>> 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)
          View Code
      •   鸭子类型
        •   多态:一种类型具有多种类型的能力,允许不同的对象对同一消息做出灵活的反应,以一种通用的方式对待可使用的对象,非动态语言必须通过继承和接口实现
        •   通过继承实现多态,子类通过重载父类的方法实现多态
          • #对于继承了同一个类的子类,当父类可以在函数中最为参数调用时,子类也是同样可以的,这就是通过继承实现多态
            >>> 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()
          View Code
      •   设计模式:用来提高代码复用和可维护性的方式,很好的指导软件设计过程,是成功的软件设计模式和体系结构,用于解决特定类型的问题的面向对象编程模型
        •   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))
            View Code
          •   工厂模式
          • #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)))
            View Code
          •   策略模式:让一个对象的某个方法可以随时改变。不用更改对象代码;对于动态类型的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()
            View Code
          • #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()
            View Code
      •   设计模式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()
          View Code
        • #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()
          View Code
        • #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()
          View Code
      •   通过组合来构建复杂的对象
        •   组合:零件:基础类;机器:包含其他类的类。组合:零件+机器;体现自下而上的编程方法
        •   组合案例--雪人:
        • #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()
          View Code

      

  • 相关阅读:
    flash处理安全策略
    flash builder 命令行创建 AsDoc
    如何永久关闭选项"Tools > Close Other Forms"
    Oracle EBS Reports 日期格式 与 客户端日期格式(控制面板 > 区域和语言选项)
    ora00600 Metalink ID: 752428.1
    如何修改台EBS的用户密码
    dbms_utility.format_error_backtrace() 返回错误行
    SQL*PLUS命令的使用大全
    APPPER50022 (system administrator > profile > system . HR:User Type)
    客户端连接数据时会报“ORA12537:TNS连接已关闭”
  • 原文地址:https://www.cnblogs.com/Kobe10/p/5708393.html
Copyright © 2011-2022 走看看