zoukankan      html  css  js  c++  java
  • Python之旅.第五章.面向对象.

    一、封装的property

    BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

     

    成人的BMI数值:

    过轻:低于18.5

    正常:18.5-23.9

    过重:24-27

    肥胖:28-32

    非常肥胖, 高于32

    体质指数(BMI=体重(kg÷身高^2m

     

    首先需要明确。bmi是算出来的,不是一个固定死的值,也就说我们必须编写一个功能,每次调用该功能都会立即计算一个值,但很明显人的bmi值听起来更像一个名词而非动词,于是我们需要为bmi这个函数添加装饰器将其伪装成一个数据属性

     

    class People:

        def __init__(self,name,weight,height):

            self.name=name

            self.weight=weight

            self.height=height

     

        @property

        def bmi(self):

            return self.weight / (self.height * self.height)

     

    egon=People('egon',75,1.80)

    print(egon.bmi) #23.148148148148145

    egon.weight=70    #可以为weight改值,bmi˙之变化

    print(egon.bmi) #21.604938271604937,调用egon.bmi本质就是触发函数bmi的执行,从而拿到其返回值

     

    egon.bmi=123 # 报错,egon.bmi背后对应的是一个函数,所以不能赋值

     

    # 了解

    class People:

        def __init__(self,name):

            self.__name=name

     

        @property

        def name(self): #obj.name

            print('您现在访问的是用户名。。。')

            return self.__name

     

        @name.setter #obj.name='EGON' # @property装饰的函数可以掉setterdeleter

        def name(self,x):

            if type(x) is not str:

                raise TypeError('名字必须是str类型')

            self.__name=x

     

        @name.deleter

        def name(self):

            # print('就不让你删')

            del self.__name

     

    obj=People('egon')

     

    print(obj.name)   #

     

    obj.name='EGON'   #

    print(obj.name)

    obj.name=123    #限制改

     

    del obj.name    #

    obj.name

     

    #property, classmethodstaticmethod为面向对象中的三大函数

    #用装饰器property将数据属性藏起来,进行查改删操作,用户无感

     

    二、多态

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

     

    为什要用多态:用基类创建一套统一的规则,强制子类去遵循(使用抽象类实现),这样便可以在不用考虑对象具体类型的前提下而直接使用对象下的方法。多态在程序中表现可以是继承,但单纯意义伤的继承无法让父类严格限制子类。

     

    多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法

     

    如何用多态

    import abc #abstract class

    class Animal(metaclass=abc.ABCMeta):

        @abc.abstractmethod

        def eat(self):

            pass

     

        @abc.abstractmethod

        def drink(self):

            pass

     

        @abc.abstractmethod

        def run(self):

            pass

     

        @abc.abstractmethod

        def bark(self):

            pass

     

    class Cat(Animal):

        def eat(self):

            print('cat eat')

     

        def drink(self):

            print('cat drink')

     

        def run(self):

            print('cat run')

     

        def bark(self):

            print('喵喵喵')

     

    class Dog(Animal):

        def eat(self):

            print('dog eat')

     

        def drink(self):

            print('dog drink')

     

        def run(self):

            print('dog run')

     

        def bark(self):

            print('汪汪汪')

     

    obj=Animal() # 报错,抽象基类本身不能被实例化

    c=Cat()   #当子类的定义形式不符合要求是,定义阶段不报错,在调用该类定义对象时才报错

    d=Dog()

    c.bark()

    d.bark()

     

    or

     

    c=Cat()

    d=Dog()

    def BARK(animal):

        animal.bark()

     

    BARK(c)

    BARK(d)

     

    多态概念在python中纵观始终的被使用,也提现了python一切皆对象的理念

    s='hello'

    l=[1,2,3]

    t=(4,5,6)

     

    s.__len__()

    l.__len__()

    t.__len__()

    def LEN(obj):

        return obj.__len__()

    print(LEN(s))

    print(LEN(l))

    print(LEN(t))

     

    or

     

    print(len(l))

    print(len(s))

    print(len(t))

     

    三、      鸭子类型

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

     

    #python中,长得像鸭子,叫起来像鸭子,就是一只鸭子

     

    #linux中一切皆文件,皆可读写

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

     

    四、 classmethodstaticmethod

    1 绑定方法:

      在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法。  #什么装饰器都不加

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

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

     

    总的来说,类中的函数可和对象绑定,可和类绑定(classmethod),也可随都不绑定(statismethod)

     

    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):   #classmethod装饰器时,pycharm自动加参数cls,为类的绑定方法

            return cls(settings.NAME,settings.AGE)

     

    p=People('egon',19)

    p.tell()

     

    p4=People.from_conf()  #类调用不用传第一个参数,自动传参

    p4.tell()

     

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

    特性:既不跟类绑定,也不跟对象绑定,这意味着谁都能用;谁来用都是一个普通函数,也就是说没有自动传值的特性了

    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'))  #time.clock()cpu有关,每次值都不同

            return m.hexdigest()

     

    obj=People('egon',18)

    obj.tell() #print(obj.uid,obj.name,obj.age)

     

    print(obj.create_id())     #对象可调用

    print(People.create_id())  #类可调用

  • 相关阅读:
    为EasySharding.EFCore提供Dapper相关查询扩展
    古典音乐作品编号标记解读
    乐理基础
    音乐指挥家
    2021年,年终总结
    有关Android launchMode 在APP(task)之间的应用——扔物线视频
    Springboot Jpa 有关多数据源的问题
    Python运算符及优先级
    高中信息技术(Python)重难点4:切片
    高中信息技术(Python)必修1 数据与计算 出现的模块和函数
  • 原文地址:https://www.cnblogs.com/yangli0504/p/8856320.html
Copyright © 2011-2022 走看看