• 4月16日 python学习总结 封装之property、多态 、classmethod和staticmethod


    一、封装之property

      @property把一个函数伪装成一个数据类型

       @伪装成数据的函数名.setter   控制该数据的修改,修改该数据时触发

       @伪装成数据的函数名.delect  控制该数据的删除,删除该数据时触发

    class People:
        def __init__(self,name):
            self.__name=name
    
    
        @property                  #将name()函数伪装成一个数据属性name
        def name(self): #obj.name
            print('您现在访问的是用户名。。。')
            return self.__name
    
        @name.setter #obj.name='EGON'      执行 name=x 修改 name 值时触发该方法
        def name(self,x):
            # print('=================',x)
            if type(x) is not str:
                raise TypeError('名字必须是str类型,傻叉')
            self.__name=x
    
        @name.deleter         # 执行 del 对象.name 时触发该方法
        def name(self):
            # print('就不让你删')
            del self.__name
    
    obj=People('egon')
    
    # print(obj.name)
    # print(obj.name())
    
    # print(obj.name)
    
    # obj.name='EGON'
    
    # print(obj.name)
    
    # obj.name=123
    
    del obj.name
    obj.name

     

     

    二、多态    

    1、 什么是多态
          多态指的是同一种事物多种形态  

    2、为什要用多态
    用基类创建一套统一的规则,强制子类去遵循(使用抽象类实现),这样便可以
    在不用考虑对象具体类型的前提下而直接使用对象下的方法

    3、多态性:一种调用方式,不同的执行效果(多态性)

        注意:多态与多态性是两种概念

        4、多态的使用

        • 继承 
          class Animal:
              def eat(self):
                  pass
              def bark(self):
                   print('')
          
          class Cat(Animal):
              def jiao(self):
                  print('喵喵喵')
          
          class Dog(Animal):
              def speak(self):
                  print('汪汪汪')
          
          class Pig(Animal):
              def han(self):
                  print('哼哼哼')
          
          c=Cat()
          d=Dog()
          p=Pig()
          
          
          # 多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法
          # c.eat()
          # d.eat()
          # p.eat()
          
          # d.bark()
          # p.bark()
          # c.bark()
          
          d.speak()
          c.jiao()
          p.han()
           
        • 抽象类
          import abc #abstract class
          class Animal(metaclass=abc.ABCMeta):
              @abc.abstractmethod
              def eat(self):
                  pass
          
              @abc.abstractmethod
              def bark(self):
                  pass
          
          # obj=Animal() # 抽象基类本身不能被实例化
          
          class Cat(Animal):
              def eat(self):
                  print('cat eat')
          
              def bark(self):
                  print('喵喵喵')
          
          class Dog(Animal):
              def eat(self):
                  print('dog eat')
          
              def bark(self):
                  print('汪汪汪')
          
          class Pig(Animal):
              def eat(self):
                  print('pig eat')
              def bark(self):
                  print('哼哼哼')
          
          c=Cat()
          d=Dog()
          p=Pig()
          
          
          # c.bark()
          # d.bark()
          # p.bark()
          
          
          # def BARK(Animal):       向上转型
          #     Animal.bark()
          #
          #
          # BARK(c)
          # BARK(d)
          # BARK(p)
        • 鸭子类型(长得像鸭子就被当作是鸭子)
          class Foo:
              def f1(self):
                  print('from foo.f1')
          
              def f2(self):
                  print('from foo.f2')
          
          class Bar:
              def f1(self):
                  print('from bar.f1')
          
              def f2(self):
                  print('from bar.f2')
          
          
          obj1=Foo()
          obj2=Bar()
          
          
          obj1.f1()
          obj1.f2()
          
          obj2.f1()
          obj2.f2()
          
          
          
          
          class Disk:
              def read(self):
                  print('disk read')
          
              def write(self):
                  print('disk write')
          
          
          class Txt:
              def read(self):
                  print('txt read')
          
              def write(self):
                  print('txt write')
          
          
          class Process:
              def read(self):
                  print('process read')
          
              def write(self):
                  print('process write')
          
          
          obj1=Disk()
          obj2=Txt()
          obj3=Process()
          
          
          obj1.read()
          obj2.read()
          obj3.read()

    三、classmethod和staticmethod

      classmethod 

              绑定方法:

          在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法

          1.  绑定对象的方法特殊之处:

              应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入

       2.  绑定到类的方法特殊之处:

              应该由类来调用,类来调用,会自动将类当作第一个参数传入  

    import settings
    
    class People:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def tell(self):
            print('%s:%s' %(self.name,self.age))
    
        @classmethod
        def from_conf(cls):
            return cls(settings.NAME,settings.AGE)
    
    
    # p=People('egon',19)
    # p.tell()
    
    # p1=People(settings.NAME,settings.AGE)
    # p1.tell()
    
    # p2=People(settings.Name,settings.AGE)
    
    
    # p3=People('alex',74)
    # p3.tell()
    
    # print(People.from_conf)
    # p4=People.from_conf(People)
    # print(People.from_conf)
    # p4=People.from_conf()
    # p4.tell()

          

    2、staticmethod:

    非绑定方法,就是一个普通函数

    特性: 既不跟类绑定,也不跟对象绑定,这意味着谁都能用

               谁来用都是一个普通函数,也就是说没有自动传值的特性了

    import settings
    import hashlib
    import time
    
    class People:
        def __init__(self,name,age):
            self.uid=self.create_id()
            self.name=name
            self.age=age
    
        def tell(self):
            print('%s: %s:%s' %(self.uid,self.name,self.age))
    
        @classmethod
        def from_conf(cls):
            return cls(settings.NAME,settings.AGE)
    
        @staticmethod
        def create_id():
            m=hashlib.md5()
            m.update(str(time.clock()).encode('utf-8'))
            return m.hexdigest()
    
    obj=People('egon',18)
    # print(obj.uid,obj.name,obj.age)
    # obj.tell()
    
    # print(obj.create_id)
    # print(People.create_id)
    
    print(obj.create_id())
    print(People.create_id())

    作业、

    '''
    4月16
    '''
    '''
    1、定义MySQL类(参考答案:http://www.cnblogs.com/linhaifeng/articles/7341177.html#_label5)
          1.对象有id、host、port三个属性
          2.定义工具create_id,在实例化时为每个对象随机生成id,保证id唯一
          3.提供两种实例化方式,方式一:用户传入host和port 方式二:从配置文件中读取host和port进行实例化
          4.为对象定制方法,save和get_obj_by_id,save能自动将对象序列化到文件中,文件路径为配置文件中DB_PATH,文件名为id号,
              保存之前验证对象是否已经存在,若存在则抛出异常,;get_obj_by_id方法用来从文件中反序列化出对象
    '''
    import hashlib
    import time
    import pickle
    import os
    from days22 import setting
    
    
    class MySQL:
        def __init__(self, host, port):
            self.__host = host
            self.__port = port
            self.__id = self.create_id()
    
        @staticmethod
        def create_id():
            m = hashlib.md5()
            m.update(str(time.clock()).encode('utf-8'))
            return m.hexdigest()
    
        @classmethod
        def creae_mysql(cla):
            return cla(setting.HOST, setting.PORT)
    
        def save(self):
            path = os.path.join(setting.DB_PATH, '%s.pk' % self.__id)
            if os.path.exists(path):
                raise ImportError('该id已存在')
            else:
                with open(path, 'wb')as f:
                    pickle.dump(self, f)
    
        def get_obj_by_id(self):
            path = os.path.join(setting.DB_PATH, '%s.pk' % self.__id)
            if not os.path.exists(path):
                raise ImportError('该id不存在')
                # print('该id不存在')
            else:
                with open(path, 'rb')as f:
                    return pickle.load(f)
    
    # m1 = MySQL('h1', 'p1')
    # m2 = MySQL.creae_mysql()
    #
    # m2.save()
    # print(m2.get_obj_by_id().__dict__)
    #
    # # m1.save()
    # m1.get_obj_by_id()
    
    '''
    2、定义一个类:圆形,该类有半径,周长,面积等属性,将半径隐藏起来,将周长与面积开放
        参考答案(http://www.cnblogs.com/linhaifeng/articles/7340801.html#_label4)
    '''
    class Circle:
        def __init__(self,radius):
            self.__radius=radius
        @property
        def perimeter(self):
            return 2*(3.14)*self.__radius
        @property
        def area(self):
            return (3.14)*(self.__radius**2)
    
    # c1=Circle(3)
    # print(c1.area)
    # print(c1.perimeter)
    
    '''
    3、明日默写
            1、简述面向对象三大特性:继承、封装、多态
                继承:继承是一种新建类的方式,新建类称之为子类或派生类,父类称之为基类或者超类,子类会‘遗传’父类的属性
                封装:装就是把一对属性装起来,封就是把这些属性藏起来
                      封装对外隐藏,对内开放
                多态:一种事物的多种形态;多态主要体现在继承、抽象类抽象方法、鸭子类型
                多态性:调用同方一方法,有不同的执行效果
            2、定义一个人的类,人有名字,身高,体重,用property讲体质参数封装成人的数据属性
                class People:
                    def __init__(self,name,hight,weight):
                        self.__name=name
                        self.__hight=hight
                        self.__weight=weight
                    @property
                    def bmi(self):
                        return self.__weight/(self.__hight**2)
            3、简述什么是绑定方法与非绑定方法,他们各自的特点是什么?
                绑定方法:在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法
                         若该函数是绑定给类用的,称之为类的绑定方法
                非绑定方法:既不跟类绑定,也不跟对象绑定,这意味着谁都能用 
                           谁来用都是一个普通函数,也就是说没有自动传值的特性了
    '''

        

  • 相关阅读:
    【转】虚拟机 NAT网络设置
    [转载]应用 Valgrind 发现 Linux 程序的内存问题
    Visual Studio 代码格式化插件(等号自动对齐、注释自动对齐等)
    【转】链接任意目录下库文件(解决错误“/usr/bin/ld: cannot find -lxxx”
    C语言实现封装、继承和多态
    美国专利搜索网站
    【转】基于OCS实现高速缓存
    【转】防止网页被搜索引擎、爬虫和网页采集器收录或克隆复制的方法汇总
    [转]机器学习和计算机视觉----数学基础
    [转]机器学习与数据挖掘的学习路线图
  • 原文地址:https://www.cnblogs.com/95lyj/p/8856367.html
Copyright © 2020-2023  润新知