面向对象基础剩余

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

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

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

猜你喜欢

转载自www.cnblogs.com/yftzw/p/8856850.html