zoukankan      html  css  js  c++  java
  • python基础之封装

    在类内部定义的函数无非三种用途
    一:绑定到对象的方法
    只要是在类内部定义的,并且没有被任何装饰器修饰过的方法,都是绑定到对象的

    class Foo:
    def test(self): #绑定到对象的方法
    pass
    def test1(): #也是绑定到对象的方法,只是对象.test1(),会把对象本身自动传给test1,因test1没有参数所以会抛出异常
    pass

    绑定到对象,指的是:就给对象去用,
    使用方式:对象.对象的绑定方法(),不用为self传值
    特性:调用时会把对象本身当做第一个参数传给对象的绑定方法


    二:绑定到类的方法:classmethod
    在类内部定义的,并且被装饰器@classmethod修饰过的方法,都是绑定到类的

    class Foo:
    def test(self): #绑定到对象的方法
    pass
    def test1(): #也是绑定到对象的方法,只是对象.test1(),会把对象本身自动传给test1,因test1没有参数所以会抛出异常
    pass

    绑定到对象,指的是:就给对象去用,
    使用方式:对象.对象的绑定方法()
    特性:调用时会把对象本身当做第一个参数传给对象的绑定方法


    三:解除绑定的方法:staticmethod
    既不与类绑定,也不与对象绑定,不与任何事物绑定
    绑定的特性:自动传值(绑定到类的就是自动传类,绑定到对象的就自动传对象)
    解除绑定的特性:不管是类还是对象来调用,都没有自动传值这么一说了

    所以说staticmethod就是相当于一个普通的工具包


    class Foo:
    def test1(self):
    pass
    def test2():
    pass


    @classmethod
    def test3(cls):
    pass
    @classmethod
    def test4():
    pass



    @staticmethod
    def test5():
    pass

    test1与test2都是绑定到对象方法:调用时就是操作对象本身
    <function Foo.test1 at 0x0000000000D8E488>
    <function Foo.test2 at 0x0000000000D8E510>
    test3与test4都是绑定到类的方法:调用时就是操作类本身
    <bound method Foo.test3 of <class '__main__.Foo'>>
    <bound method Foo.test4 of <class '__main__.Foo'>>
    test5是不与任何事物绑定的:就是一个工具包,谁来都可以用,没说专门操作谁这么一说
    <function Foo.test5 at 0x0000000000D8E6A8>

    四.什么是property,如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?
    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
    为什么要用property:将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

    封装概念:

    property代码1

    import math
    class Circle:
        def __init__(self,radius):  #圆的半径
            self.radius=radius
        @property   #添加装饰器,area=property(area)
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property   #添加装饰器,perimeter=property(perimeter)
        def perimeter(self):
            return 2*math.pi*self.radius    #计算周长
    c=Circle(7)
    c.radius=10
    print(c.radius) #打印出圆的半径
    # print(c.area()) #会报错,TypeError: 'float' object is not callable,译为:float对象是不可调用的
    # print(c.perimeter())    #float对象是不可调用的
    print(c.area)   #表面上是一个数据属性,但这个根本上是一个函数属性,会调用上面的area函数,打印圆的面积
    print(c.perimeter)  #打印圆的周长
    代码片段1

    property代码2

    class People:
        def __init__(self,name,age,height,weight):
            self.name=name
            self.age=age
            self.height=height
            self.weight=weight
        @property #该装饰器可以理解为bodyindex=property(bodyindex)
        def bodyindex(self):    #计算体脂
            return self.weight/(self.height**2)
    
    p1=People('cobila',18,1.65,75)
    print(p1.bodyindex)   #过轻:低于18.5,正常:18.5-23.9,过重:24-27,肥胖:28-32,非常肥胖, 高于32
    p1.weight=200
    print(p1.bodyindex)
    代码片段2

    property代码3

    class People:
        def __init__(self,name):
            self.__name=name    #self.__name
    
        # def tell_name(self):
        #     return self.__name
        @property
        def name(self):
            return self.__name
    p1=People('cobila')
    # print(p1.tell_name())
    print(p1.name)  #触发name()函数的运行
    # p1.name='egon'    #会报错,AttributeError: can't set attribute
    代码片段3

    property代码4

    class People:
        def __init__(self,name,SEX):
            self.name=name
            self.__sex=SEX  #self.sex='male' p1.sex(相当于self.sex)='male'
        @property #
        def sex(self):
            return self.__sex   #p1.__sex
        @sex.setter #修改
        def sex(self,value):    #性别是字符串类型
            # print(self,value) #
            if not isinstance(value,str):   #python没有类型限制,所以只能自己加这种类型限制
                raise TypeError("性别必须是字符串类型")
            self.__sex=value    #p1.__sex='male'
        @sex.deleter    #删除
        def sex(self):
            del self.__sex #触发delete函数的运行,del p1.__sex
            # del self.sex  #这是错误的
    # p1=People('cobila','male')
    # print(p1.sex)
    # p1.sex='123'
    # p1.sex = 'female'   #这个等式触发def sex(self,value)的运行,把female这个值传给value
    # print(p1.sex)   #输出female
    # p1.sex=9999999    #由于更改的不是字符串类型,所以会抛出异常
    # p1=People('cobila',9999999999999999)    #这里更改的是def sex(self):下面的self.__sex
    
    p1=People('cobila','male')  #实例化触发__init__的运行
    print(p1.sex)   #输出male
    # del p1.sex  #@sex.deleter一执行它(def sex(self)),del self.sex,无限递归,一直删除自己,会报错(RecursionError: maximum recursion depth exceeded)
    # print(p1.sex)
    代码片段4
  • 相关阅读:
    Oracle 11g R2 常用配置与日志的文件位置
    DBA常用SQL之会话与等待事件
    SSH框架之Spring第三篇
    SSH框架之Spring第二篇
    SSH框架之Spring第一篇
    SSH框架之Struts2第三篇
    SSH框架之Struts2第一篇
    SSH框架之Struts2第二篇
    SSH框架之Hibernate第四篇
    SSH框架之Hibernate第三篇
  • 原文地址:https://www.cnblogs.com/bingabcd/p/6746725.html
Copyright © 2011-2022 走看看