python面向对象-学习笔记(五、属性相关的补充)

发布时间 2023-10-29 15:44:01作者: 阿慢2010

私有化属性

  • 注意

    • python并没有真正支持私有化,但是可以使用下划线完成伪私有的效果
    • 类属性(方法)和实例属性(方法)遵循相同的规则
  • 公有属性a

    • 在类的内部 可以访问
    • 在子类的内部 可以访问
    • 在模块其他地方
      • 类的属性 可以访问
      • 子类的属性 可以访问
      • 类的实例的属性 可以访问
      • 子类的实例的属性 可以访问
    • 模块外部
      • 通过import方式导入模块 可以访问
      • 通过from...import...方式导入模块 可以访问
  • 受保护属性_a (下划线a)

    • 在类的内部 可以访问
    • 在子类的内部 可以访问
    • 在模块其他地方
      • 类的属性 可以访问,但是有提示
      • 子类的属性 可以访问,但是有提示
      • 类的实例的属性 可以访问,但是有提示
      • 子类的实例的属性 可以访问,但是有提示
    • 模块外部
      • 通过import方式导入模块 可以访问,但是会提示
      • 通过from...import...方式导入模块 无法访问
  • 私有属性__a (双下划线a)

    • 在类的内部 可以访问
    • 在子类的内部 无法访问
    • 在模块其他地方
      • 类的属性 无法访问
      • 子类的属性 无法访问
      • 类的实例的属性 无法访问
      • 子类的实例的属性 无法访问
    • 模块外部
      • 通过import方式导入模块 可以访问
      • 通过from...import...方式导入模块 无法访问
  • 通过这个属性设置,可以让from...import...导包的时候可以被访问

    • all = ["a", "_a", "__a"]

私有属性的实现机制

  • 名字重整(Name Mangling)
    • 重改__a为另外一个名称
      • _类名__a
  • 目的
    • 防止外界直接访问
    • 防止被子类同名称属性覆盖
  • 应用场景
    • 数据保护
    • 数据过滤

只读属性

  • 概念
    • 一个属性(一般指实例属性),只能读取,不能写入
  • 应用场景
    • 有些属性,只限在内部根据不同场景进行修改,而对外界来说,只能读取,不能写入
    • 比如:电脑的网速,网络状态
  • 方式一
    • 方案
      • 全部隐藏
        • 私有化 (既不能读,也不能写)
      • 部分公开
        • 公开读的操作
    • 具体实现
      • 私有化: 通过"属性前置双下划线"实现
      • 部分公开
        • 通过公开的方法
        • 优化
          • 添加property装饰器
            • 作用
              • 将一些"属性的操作方法"关联到某一个属性中
            • 概念补充
              • 经典类,没有继承object(python2)
              • 新式类,继承object(python3默认继承object)
            • property介绍
只读属性的实现(通过公开的方法)
class Person:
    def __init__(self):
        self.__age = 18

    # 通过实例方法来模拟只读属性
    def getAge(self):
        return self.__age


p1 = Person()
print(p1.getAge())

image

只读属性的实现(优化)
class Person:
    def __init__(self):
        self.__age = 18

    # 主要作用就是,可以以使用属性的方式,来使用这个方法
    @property
    def age(self):
        return self.__age


p1 = Person()
print(p1.age)

p1.age = 666

image

property方法的使用
class Person:
    def __init__(self):
        self.__age = 18

    def get_age(self):
        return self.__age

    def set_age(self, value):
        self.__age = value

    age = property(get_age, set_age)


p = Person()
print(p.age)

p.age = 90
print(p.age)
print(p.__dict__)

image

property装饰器的使用
class Person:
    def __init__(self):
        self.__age = 18

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, value):
        self.__age = value


p = Person()
print(p.age)
p.age = 90
print(p.age)
print(p.__dict__)

image

__setattr__设置只读属性
class Person:
    # 当我们通过实例属性=值,给一个实例增加一个属性,或者说,修改一下属性值的时候,都会调用这个方法
    # 在这个方法内部,才会真正的把 这个属性以及对应的数据给存储到__dict__字典里面
    def __setattr__(self, key, value):
        print(key, value)
        if key == "age" and key in self.__dict__.keys():
            print("这个属性是只读属性,不能设置数据")
        else:
            self.__dict__[key] = value
            # # 会导致死循环
            # self.key = value


p1 = Person()
p1.age = 18
p1.name = "sz"
print(p1.age)
print(p1.__dict__)

p1.age = 999
print(p1.age)

image

内置特殊属性

  • 类属性
    • __dict__ 类的所有属性和方法
    • __bases__ 类的所有父类构成的元组(支持多继承)
    • __doc__ 类的文档字符串
    • __name__ 类的名字
    • __module__ 类所在的模块
  • 实例属性
    • __dict__ 实例的属性
    • __class__ 实例对应的类
系统内置属性
class Person:
    """
    这是一个人
    """
    age = 19

    def __init__(self):
        self.name = "sz"

    def run(self):
        print("run")


print(Person.__dict__)
print(Person.__bases__)
print(Person.__doc__)
print(Person.__name__)
print(Person.__module__)

p = Person()
print(p.__dict__)
print(p.__class__)

image


学习链接: 【Python】零基础入门 面向对象编程(强烈推荐)