zoukankan      html  css  js  c++  java
  • 面向对象基础剩余

    property

    首先我们来看一个例子:

    '''
    BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
    
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
    
    '''
    class Peopele:
        def __init__(self,name,weight,higiht):
            self.name=name
            self.weight=weight
            self.higiht=higiht
    
        def bmi(self):
            return self.weight/(self.higiht*self.higiht)
    obj=Peopele('egon',75,1.75)
    print(obj.bmi())

    从列子当中 我们可以的看出 bmi是一个跟体重,身高一样的名词,我们却用调用动词的方式加括号去调用它,这样就会导致 不知情的人去调用bmi这个名词 却要先找到它所对应的函数 然后再用调用 函数的方式 去调用它,怎么样能像调用身高,体重那样去调用bmi那 我们就需要用到property,请看下面:

    #使用property(装饰器,将其伪装成一个数据属性)
    class Peopele:
        def __init__(self,name,weight,higiht):
            self.name=name
            self.weight=weight
            self.higiht=higiht
        @property
        def bmi(self):
            return self.weight/(self.higiht*self.higiht)
    obj=Peopele('egon',75,1.75)
    print(obj.bmi)

    有一点需要注意 因为bmi的本质是个函数,它只是被property伪装成一个数据属性 所以我们无法去赋值

    我们举个实际例子 来说明property的牛逼之处

    #使用property的实际例子对比
    # 没有使用
    class School:
        def __init__(self,name):
            self.__name=name
        def get_name(self):
            return self.__name
        def setter_name(self,x):
            if type(x) is not str:
                raise TypeError('名字必须是str类型,傻叉')
            self.__name=x
        def del_name(self):
            print('就不让你删')
            del self.__name
    res=School('egon')
    res.setter_name('EGON')
    print(res.get_name())
    del res.del_name
    # print(res.get_name)
    #报错
    EGON
    
    Traceback (most recent call last):
      File "C:/Users/64802/PycharmProjects/kaoshi/学习/学习/day22/property.py", line 52, in <module>
        del res.del_name
    AttributeError: del_name
    #不是报找不到slef.name这个值的错误 就说明 我们没有成功删掉
    class School:
        def __init__(self,name):
            self.__name=name
        @property
        def get_name(self):
            return self.__name
        @get_name.setter
        def setter_name(self,x):
            if type(x) is not str:
                raise TypeError('名字必须是str类型,傻叉')
            self.__name=x
        @get_name.deleter
        def del_name(self):
            print('就不让你删')
            del self.__name
    res=School('egon')
    res.setter_name='EGON'
    print(res.get_name)
    del res.del_name
    print(res.get_name)
    #报错说 我找不到学校名字这个值 说明删除成功
    AttributeError: 'School' object has no attribute '_School__name'

    上述例子中@都是一些固定的用法记住既可以,我们的调用完全符合了我们所需要的

    多态

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

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

    #都是一些固定用法 记住即可 意思就是强制你父类有什么 是什么样的函数你必须一样 不然就会在调用阶段报错,我们也知道在定义阶段
    #只会执行类体内代码,把产生的名字放进存在类的名称空间,函数的话只会检测函数体内语法
    import abc
    class 动物(metaclass=abc.ABCMeta):
        @abc.abstractclassmethod
        def eat(self):
            print('eat')
        @abc.abstractclassmethod
        def run(self):
            print('run')
    class Cat(动物):
        def eat(self):
            print('cat eat')
        def run(self):
            print('cat run')
    class Dog(动物):
        def eat(self):
            print('dog eat')
        def run(self):
            print('dog run')
    res=Cat()
    res.eat()

    鸭子类型

    #鸭子类型(走路像鸭子,看起来像鸭子,你就是鸭子)
    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()
    #我们俗成规定并没有什么强制性,符合python的风格,它的意思是和多态一样的 但是没有父类子类一说

    classmethod

    绑定方法:
        在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法
        绑定对象的方法特殊之处:
            应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入

        绑定到类的方法特殊之处:
            应该由类来调用,类来调用,会自动将类当作第一个参数传入

    import settings
    class People:
        def __init__(self,name,age):
            self.__name=name
            self.__age=age
        def info(self):
            print('''
            姓名:%s
            年龄:%s
            '''%(self.__name,self.__age))
        @classmethod
        def get_info(cls):
            return cls(settings.name,settings.age)
    obj=People.get_info()
    obj.info()

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

    import setttings
    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())

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

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

  • 相关阅读:
    Jmeter 调试接口用例怎么判断提取的上一个接口返回值是正确的?
    Jmeter 加密处理方法
    Apache Ignite 学习
    jmeter 中 浮点数计算精度问题
    httprunner 使用总结
    oh-my-zsh 安装及使用
    内置装饰器二:@property
    内置装饰器一:@classmethod、@staticmathod
    python实现列表的排序
    Mac git简易使用
  • 原文地址:https://www.cnblogs.com/yftzw/p/8856850.html
Copyright © 2011-2022 走看看