• day22-类的封装、property特性以及绑定方法与非绑定方法


    类的封装

    将类的属性或方法隐藏,这些属性和方法只能在内部使用,外部无法使用。类的封装在类定义阶段就执行了,会把私有属性_x变成_类名__x

    两个层面的封装

    第一个层面

    第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方法去访问里面的名字,这本身就是一种封装

    第二个层面

    第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的)只在类的内部使用、外部无法访问,或者留下少量接口(函数)功外部访问

    在python中用双下划线的方式实现隐藏属性(设成私有的)

    class People:
        __name = 'nick'  # 设置成私有属性,在内部可以使用,在外部无法使用
        print(__name)  # nick
        
        def __sleep(self):
            print('from People')
        
        def eat(self):
            print('from eat')
    
    peo = People()
    peo.eat()  # from eat
    peo.__name()  # 打印报错 'People' object has no attribute '__name'
    peo.__sleep()  # 打印报错 'People' object has no attribute '__sleep'
    

    如果要想访问有属性可以通过“_类名__私有属性”来使用

    class People:
        __name = 'nick'
        
    peo = People()
    print(peo._People__name)
    
    nick
    

    封装的好处

    • 数据封装:将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制
    • 封装方法:目的是隔离复杂度

    私有模块

    就是在模块内定义私有属性或函数如:_name = 'nick',在导入该模块时from module import * 无法导入该私有属性_name,若要导入则使用from module import _x

    类的propertry特性

    property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接使用

    # 没加property装饰器
    class People:
        def __init__(self, height, weight):
            self.height = height
            self.weight = weight
            
        def bmi(self):
            return self.weight/(self.height ** 2)
        
    peo = People(1.8, 70)
    print(peo.bmi())
    
    21.604938271604937
    
    class People:
        def __init__(self, height, weight):
            self.height = height
            self.weight = weight
        
        @property  # 将装饰器后,将bmi函数伪装成一个数据属性
        def bmi(self):
            return self.weight/(self.height ** 2)
        
    peo = People(1.8, 70)
    print(peo.bmi)  # 不用加括号直接使用
    
    21.604938271604937
    

    setter 和 deleter

    class People():
    
        def __init__(self,height,weight):
            self.height = height
            self.weight = weight
    
        @property  # 获取值的时候触发,你不需要加括号使用,不能加参数
        def bmi(self):
            return self.weight/(self.height**2)
    
        @bmi.setter  # 在修改bmi的时候触发,必须得加参数
        def bmi(self, value):
            print(f'不能修改成{value}')
    
        @bmi.deleter  # 在删除bmi的时候触发,不能加参数
        def bmi(self):
            print('delter')
    
    peo = People(1.8,70)
    print(peo.bmi)
    
    print('*'*50)
    peo.bmi = 50
    print(peo.bmi)
    
    print('*'*50)
    del peo.bmi
    print(peo.bmi)
    
    21.604938271604937
    **************************************************
    不能修改成50
    21.604938271604937
    **************************************************
    delter
    21.604938271604937
    

    类与对象的绑定方法与非绑定方法

    绑定给谁,就将谁传给函数中的第一个参数作为self

    class F:
        
        # 默认绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参
        def f1(self):  
            print(self)
        
        # 绑定给类的方法,类能使用,对象也能使用,但是参数依然是类
        @classmethod  # 让被装饰的函数给类使用,约定俗成参数为cls
        def f2(cls):
            print(cls)
        
        # 什么都不绑定,非绑定方法,定义为普通的函数
        @staticmethod
        def f3(self):
            print(self)
        
    f = F()
    f.f1()  
    F.f1(111)
    print("*" * 30)
    
    f.f2()
    F.f2()
    print("*" * 30)
    
    f.f3('from f')
    F.f3('from F')
    
    <__main__.F object at 0x000001CE0E2EDFD0>
    111
    ******************************
    <class '__main__.F'>
    <class '__main__.F'>
    ******************************
    from f
    from F
    

    总结

    • 对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法
    • 类的绑定方法:加了@classmethod装饰器的方法就是类的绑定方法
    • 非绑定方法:加了@staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数
  • 相关阅读:
    深入源码之JDK Logging
    随机数生成器
    简单日志LogHelper
    Xml、Json序列化
    Redis封装之Set
    Redis封装之Hash
    Redis封装之String
    Redis之创建
    AngularJS初接触
    简单缓存Cache
  • 原文地址:https://www.cnblogs.com/863652104kai/p/11059352.html
Copyright © 2020-2023  润新知