029.Python面向对象_类补充_属性(方法)相关

news2025/1/12 15:59:05

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线
@TOC

私有化(隐藏)属性/方法

概念

  • 把原本访问范围比较大的属性,设置一个权限,让其访问范围变小

用途示例

  • 示例1:人的体重变化
    class Person:
        # 体重属性
        weight = 65
    
        def eat(self):
            print('通过吃东西增加体重...')
        
        def exercise(self):
            print('通过运动减少体重.....')
    
    
    # 这个人的类里面有一个体重属性 weight ,这是一个类属性
    # 那么我们可以在类内部拿到这个属性,也可以通过实例在类外部拿到这个属性,并进行修改
    # 这个体重可以随意变化,显然不是很靠谱
    # 对于体重的变化,我们希望只能通过吃东西(eat())和运动(exercise())方法来进行调整
    # 所以我们需要将weight这个属性进行私有化
    
  • 示例2:银行余额变化
    class Bank:
        # 余额属性
        surplus = 1000
        
        def save_money(self):
            print('通过存钱,使余额变多......')
        
        def draw_money(self):
            print('通过取钱,使余额变少......')
    
    # 这个银行的类里面有一个余额属性 surplus ,这是一个类属性
    # 那么我们可以在类内部拿到这个属性,也可以通过实例在类外部拿到这个属性,并进行修改
    # 这余额可以随意修改,显然不是很安全
    # 对于余额的变化,我们希望只能通过存款(save_money())和取款(draw_money())方法来进行修改
    # 所以我们需要将 surplus 这个属性进行私有化
    
  • 示例3:买包子
    class Person:
        def __run(self):
            print('出门跑步去包子店...')
    
        def __pay(self):
            print('拿手机扫码付钱给老板...')
    
        def __take_bun(self):
            print('老板从蒸笼里面拿出包子给我...')
            
        def buy_bun(self):
            """买包子"""
            self.__run()
            self.__pay()
            self.__take_bun()
            
    
    # 在这个人的类里面,有一个买包子的功能,但是这个功能又被分成了无数个小功能
    # 但是,我们实例化一个人的时候,只需要他执行买包子功能,其他那些小的功能就没必要都让执行者看到了
    # 将其他方法私有化(隐藏)后,在实例调用方法的时候就看不到这些小功能了
    

注意事项

  • 在其他某些语言中可以通过关键字指定属性为私有属性(public int id
  • 但是,在Python中并没有真正的私有化支持,只能使用下划线完成伪私有的效果
  • 类属性(方法)和实例属性(方法)遵循相同的规则

不同属性各区域访问权限

区域划分
  • 分区

    • 类内部区域
    • 子类内部区域
    • 模块内部其他区域
    • 模块外部区域(跨模块)
  • 分区图解

    • 在这里插入图片描述
  • 访问权限

    • 在这里插入图片描述
公有属性(x)
  • 访问权限
    • 类内部访问
      • 可以访问模块公有属性
      • 可以访问类公有属性
    • 子类内部访问
      • 可以访问模块公有属性
      • 可以访问类公有属性
    • 模块内其他位置访问
      • 可以访问模块公有属性
      • 可以访问类公有属性
    • 跨模块访问
      • from 模块 import 类 形式导入
        • 不可以访问模块公有属性
        • 可以访问类公有属性
      • import 模块 形式导入
        • 可以访问模块公有属性
        • 可以访问类公有属性
      • from 模块 import * 形式导入
        • 可以访问模块公有属性
        • 可以访问类公有属性
  • 代码示例
  • super_class模块代码(super_class.py)
    m = '模块公有属性m'
    n = '模块公有属性n'
    
    
    class Animal:
        x = '类公有属性x'
        y = '类公有属性y'
    
        def A_test(self):
            print('类内部访问类属性:', Animal.x)
            print('类内部访问类属性:', self.y)
            print('类内部访问模块属性:', m)
            print('类内部访问模块属性:', n)
            print('')
    
    
    class Dog(Animal):
        def D_test(self):
            print('子类内部访问类属性:', Dog.x)
            print('子类内部访问类属性:', self.y)
            print('子类内部访问模块属性:', m)
            print('子类内部访问模块属性:', n)
            print('')
    
    
    # =========访问权限测试========
    
    
    if __name__ == '__main__':
        # # 类内部访问
        a = Animal()
        a.A_test()
    
        # # 子类内部访问
        d =Dog()
        d.D_test()
    
        # 模块内其他位置访问
        print('模块内其他位置访问类属性,父类.类属性:', Animal.x)
        print('模块内其他位置访问类属性,派生类.类属性:', Dog.y)
        print('')
    
        print('模块内其他位置访问类属性,父类实例.类属性:', a.x)
        print('模块内其他位置访问类属性,派生类实例.类属性:', d.y)
        print('')
    
        print('模块内其他位置访问,模块属性:', m)
        print('模块内其他位置访问,模块属性:', n)
    
    # ========== 输出结果 ==========
    # 类内部访问类属性: 类公有属性x
    # 类内部访问类属性: 类公有属性y
    # 类内部访问模块属性: 模块公有属性m
    # 类内部访问模块属性: 模块公有属性n
    # 
    # 子类内部访问类属性: 类公有属性x
    # 子类内部访问类属性: 类公有属性y
    # 子类内部访问模块属性: 模块公有属性m
    # 子类内部访问模块属性: 模块公有属性n
    # 
    # 模块内其他位置访问类属性,父类.类属性: 类公有属性x
    # 模块内其他位置访问类属性,派生类.类属性: 类公有属性y
    # 
    # 模块内其他位置访问类属性,父类实例.类属性: 类公有属性x
    # 模块内其他位置访问类属性,派生类实例.类属性: 类公有属性y
    # 
    # 模块内其他位置访问,模块属性: 模块公有属性m
    # 模块内其他位置访问,模块属性: 模块公有属性n
    
    
  • sub_class模块代码(sub_class.py)
    '<!--导入方式1-->'
    # from super_class import Animal
    # """导入了一个模块中的module(模块)、class(类)、function(函数)或是variable(变量)"""
    # # print('跨模块访问模块公有属性:', m)                        # 报错: NameError: name 'm' is not defined
    # # print('跨模块访问模块公有属性:', super_class.n)            # 报错: NameError: name 'super_class' is not defined
    # # print('跨模块访问类公有属性:', x)                          # 报错: NameError: name 'x' is not defined
    # print('跨模块访问类公有属性:', Animal.y)                    # 正常访问: 跨模块访问类公有属性: 类公有属性y
    
    
    '<!--导入方式2-->'
    # import super_class
    # """导入一个模块(module)"""
    # # print('跨模块访问模块公有属性:', m)                         # 报错: NameError: name 'm' is not defined
    # print('跨模块访问模块公有属性:', super_class.n)               # 正常访问: 跨模块访问模块公有属性: 模块公有属性n
    # # print('跨模块访问类公有属性:', super_class.x)               # 报错: AttributeError: module 'super_class' has no attribute 'x'
    # print('跨模块访问类公有属性:', super_class.Animal.y)           # 正常访问: 跨模块访问类公有属性: 类公有属性y
    # print('跨模块访问父类公有属性:', super_class.Dog.x)            # 正常访问: 跨模块访问父类公有属性: 类公有属性x
    
    
    '<!--导入方式3-->'
    from super_class import *
    """"是把一个模块中所有函数都导入进来"""
    print('跨模块访问模块公有属性:', m)                            # 正常访问: 跨模块访问模块公有属性: 模块公有属性m
    print('跨模块访问模块公有属性:', super_class.n)                # 正常访问: 跨模块访问模块公有属性: 模块公有属性n
    # print('跨模块访问类公有属性:', x)                           # 报错: NameError: name 'x' is not defined
    print('跨模块访问类公有属性:', Animal.x)                      # 正常访问: 跨模块访问类公有属性: 类公有属性x
    print('跨模块访问类公有属性:', super_class.Animal.x)          # 正常访问: 跨模块访问类公有属性: 类公有属性x
    print('跨模块访问父类公有属性:', Dog.x)                        # 正常访问: 跨模块访问父类公有属性: 类公有属性x
    print('跨模块访问父类公有属性:', super_class.Dog.x)           # 正常访问: 跨模块访问父类公有属性: 类公有属性x
    
受保护类属性(_x)
  • 访问权限

    • 类内部访问
      • 可以访问模块受保护属性
      • 可以访问类受保护属性
    • 子类内部访问
      • 可以访问模块受保护属性
      • 可以访问类受保护属性
    • 模块内其他位置访问
      • 可以访问模块受保护属性
      • 可以访问类受保护属性,但是有警告
      • 可以强行访问受保护类属性,但是PyCharm会有警告提示
        Access to a protected member _x of a class (对类的受保护成员x的访问)
    • 跨模块访问
      • from 模块 import 类 形式导入
        • 不可以访问模块受保护属性
        • 可以访问类受保护属性,但是有警告
      • import 模块 形式导入
        • 可以访问模块受保护属性,但是有警告
        • 可以访问类受保护属性,但是有警告
        • 可以强行访问受保护视图,但是PyCharm会有报警提示
          Access to a protected member _x of a class (对类的受保护成员x的访问)
      • from 模块 import 类 形式导入
        • 可以访问模块受保护属性,但是需要通过__all__属性指定属性
        • 可以访问类受保护属性,但是有警告
        • 可以强行访问受保护视图,但是PyCharm会有报警提示
          Access to a protected member _x of a class (对类的受保护成员x的访问)
  • 代码示例

  • super_class模块代码(super_class.py)

    _m = '模块公有属性m'
    _n = '模块公有属性n'
    
    
    __all__ = ['_n']
    class Animal:
        _x = '类公有属性x'
        _y = '类公有属性y'
    
        def A_test(self):
            print('类内部访问类属性:', Animal._x)
            print('类内部访问类属性:', self._y)
            print('类内部访问模块属性:', _m)
            print('类内部访问模块属性:', _n)
            print('')
    
    
    class Dog(Animal):
        def D_test(self):
            print('子类内部访问类属性:', Dog._x)
            print('子类内部访问类属性:', self._y)
            print('子类内部访问模块属性:', _m)
            print('子类内部访问模块属性:', _n)
            print('')
    
    
    # =========访问权限测试========
    
    
    if __name__ == '__main__':
        # # 类内部访问
        a = Animal()
        a.A_test()
    
        # # 子类内部访问
        d =Dog()
        d.D_test()
    
        # 模块内其他位置访问
        print('模块内其他位置访问类属性,父类.类属性:', Animal._x)        # 警告:Access to a protected member _x of a class(对类的受保护成员x的访问)
        print('模块内其他位置访问类属性,派生类.类属性:', Dog._y)          # 警告:Access to a protected member _y of a class(对类的受保护成员y的访问)
        print('')
    
        print('模块内其他位置访问类属性,父类实例.类属性:', a._x)           # 警告:Access to a protected member _x of a class(对类的受保护成员x的访问)
        print('模块内其他位置访问类属性,派生类实例.类属性:', d._y)          # 警告:Access to a protected member _y of a class(对类的受保护成员y的访问)
        print('')
    
        print('模块内其他位置访问,模块属性:', _m)
        print('模块内其他位置访问,模块属性:', _n)
    
    # ========== 输出结果 ==========
    # 类内部访问类属性: 类公有属性x
    # 类内部访问类属性: 类公有属性y
    # 类内部访问模块属性: 模块公有属性m
    # 类内部访问模块属性: 模块公有属性n
    #
    # 子类内部访问类属性: 类公有属性x
    # 子类内部访问类属性: 类公有属性y
    # 子类内部访问模块属性: 模块公有属性m
    # 子类内部访问模块属性: 模块公有属性n
    #
    # 模块内其他位置访问类属性,父类.类属性: 类公有属性x
    # 模块内其他位置访问类属性,派生类.类属性: 类公有属性y
    #
    # 模块内其他位置访问类属性,父类实例.类属性: 类公有属性x
    # 模块内其他位置访问类属性,派生类实例.类属性: 类公有属性y
    #
    # 模块内其他位置访问,模块属性: 模块公有属性m
    # 模块内其他位置访问,模块属性: 模块公有属性n
    
  • sub_class模块代码(sub_class.py)

    '<!--导入方式1-->'
    # from super_class import Animal
    # """导入了一个模块中的module(模块)、class(类)、function(函数)或是variable(变量)"""
    # print('跨模块访问模块公有属性:', _m)                           # 报错: NameError: name '_m' is not defined
    # print('跨模块访问模块公有属性:', super_class._n)             # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问类公有属性:', _x)                            # 报错: NameError: name '_x' is not defined
    # print('跨模块访问类公有属性:', Animal._y)                    # 能访问: 跨模块访问类公有属性: 类公有属性_y,但是有警告Access to a protected member _y of a class
    
    
    '<!--导入方式2-->'
    # import super_class
    # """导入一个模块(module)"""
    # print('跨模块访问模块公有属性:', _m)                                # 报错: NameError: name '_m' is not defined
    # print('跨模块访问模块公有属性:', super_class._n)                  # 能访问: 跨模块访问模块公有属性: 模块受保护属性_n,但有警告Access to a protected member _n of a module
    # print('跨模块访问类公有属性:', super_class._x)                    # 报错: AttributeError: module 'super_class' has no attribute '_x'
    # print('跨模块访问类公有属性:', super_class.Animal._y)             # 能访问: 跨模块访问类公有属性: 类受保护属性_y,但有警告Access to a protected member _y of a class
    # print('跨模块访问父类公有属性:', super_class.Dog._x)               # 能访问: 跨模块访问父类公有属性: 类受保护属性_x,但有警告Access to a protected member _x of a class
    
    
    '<!--导入方式3-->'
    from super_class import *
    """"是把一个模块中所有函数都导入进来"""
    # print('跨模块访问模块公有属性:', _m)                                   # 报错: NameError: name '_m' is not defined
    # print('跨模块访问模块公有属性:', super_class._m)                     # 报错:NameError: name 'super_class' is not defined
    # print('跨模块访问模块公有属性:', _n)                                   # 通过__all__指定可以访问: 跨模块访问模块公有属性: 模块受保护属性_n
    # print('跨模块访问模块公有属性:', super_class._n)                     # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问类公有属性:', _x)                                    # 报错: NameError: name '_x' is not defined
    # print('跨模块访问类公有属性:', Animal._x)                             # 能访问: 跨模块访问类公有属性: 类受保护属性_x,但有警告Access to a protected member _x of a class
    # print('跨模块访问类公有属性:', super_class.Animal._x)               # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问父类公有属性:', Dog._x)                               # 能访问: 跨模块访问父类公有属性: 类受保护属性_x,但有警告Access to a protected member _x of a class
    # print('跨模块访问父类公有属性:', super_class.Dog._x)                 # 报错: NameError: name 'super_class' is not defined
    
    
私有化类属性(__x)
  • 访问权限
    • 类内部访问
      • 不可以访问模块私有属性
      • 可以访问类私有属性
    • 子类内部访问
      • 不可以访问模块私有属性
      • 不可以访问类私有属性
    • 模块内其他范围访问
      • 可以访问模块私有属性
      • 不可以访问类私有属性
    • 跨模块访问
      • from 模块 import 类 形式导入
        • 不可以访问模块私有属性
        • 不可以访问类私有属性
      • import 模块 形式导入
        • 可以访问模块私有属性
        • 不可以访问类私有属性
      • from 模块 import * 形式导入
        • 可以访问模块私有属性,但是需要通过__all__指定属性
        • 不可以访问类私有属性
  • 代码示例
  • super_class模块代码(super_class.py)
    __m = '模块私有化属性__m'
    __n = '模块私有化属性__n'
    
    __all__ = ['__n']
    
    
    class Animal:
        __x = '类私有化属性__x'
        __y = '类私有化属性__y'
    
        def A_test(self):
            print('类内部访问类属性:', Animal.__x)          # 正常访问:类内部访问类属性: 类私有化属性__x
            print('类内部访问类属性:', self.__y)            # 正常访问:类内部访问类属性: 类私有化属性__y
            # print('类内部访问模块属性:', __m)                # 报错:NameError: name '_Animal__m' is not defined
            # print('类内部访问模块属性:', __n)                # 报错:NameError: name '_Animal__n' is not defined
            print('')
    
    
    class Dog(Animal):
        def D_test(self):
            # print('子类内部访问类属性:', Dog.__x)            # 报错:AttributeError: type object 'Dog' has no attribute '_Dog__x'
            # print('子类内部访问类属性:', self.__y)           # 报错:AttributeError: 'Dog' object has no attribute '_Dog__y'
            # print('子类内部访问模块属性:', __m)               # 报错:NameError: name '_Dog__m' is not defined
            # print('子类内部访问模块属性:', __n)               # # 报错:NameError: name '_Dog__n' is not defined
            print('')
    
    
    # =========访问权限测试========
    
    
    if __name__ == '__main__':
        # # 类内部访问
        a = Animal()
        # a.A_test()
    
        # # 子类内部访问
        d = Dog()
        # d.D_test()
    
        # # 模块内其他位置访问
        # print('模块内其他位置访问类属性,父类.类属性:', Animal.__x)         # 报错:AttributeError: type object 'Animal' has no attribute '__x'
        # print('模块内其他位置访问类属性,派生类.类属性:', Dog.__y)          # 报错:AttributeError: type object 'Dog' has no attribute '__y'
        # print('')
        #
        # print('模块内其他位置访问类属性,父类实例.类属性:', a.__x)           # 报错:AttributeError: 'Animal' object has no attribute '__x'
        # print('模块内其他位置访问类属性,派生类实例.类属性:', d.__y)          # 报错:AttributeError: 'Dog' object has no attribute '__y'
        # print('')
        #
        print('模块内其他位置访问,模块属性:', __m)                       # 正常访问:模块内其他位置访问,模块属性: 模块私有化属性__m
        print('模块内其他位置访问,模块属性:', __n)                       # 正常访问:模块内其他位置访问,模块属性: 模块私有化属性__n
    
    
    
  • sub_class模块代码(sub_class.py)
    '<!--导入方式1-->'
    # from super_class import Animal
    # """导入了一个模块中的module(模块)、class(类)、function(函数)或是variable(变量)"""
    # print('跨模块访问模块公有属性:', __m)                            # 报错: NameError: name '__m' is not defined
    # print('跨模块访问模块公有属性:', super_class.__n)              # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问类公有属性:', __x)                              # 报错: NameError: name '__x' is not defined
    # print('跨模块访问类公有属性:', Animal.__y)                       # 报错: AttributeError: type object 'Animal' has no attribute '__y'
    
    
    '<!--导入方式2-->'
    # import super_class
    """导入一个模块(module)"""
    # print('跨模块访问模块公有属性:', __m)                                # 报错: NameError: name '__m' is not defined
    # print('跨模块访问模块公有属性:', super_class.__n)                  # 正常访问: 跨模块访问模块公有属性: 模块私有化属性__n
    # print('跨模块访问类公有属性:', super_class.__x)                    # 报错: AttributeError: module 'super_class' has no attribute '__x'
    # print('跨模块访问类公有属性:', super_class.Animal.__y)             # 报错: AttributeError: type object 'Animal' has no attribute '__y'
    # print('跨模块访问父类公有属性:', super_class.Dog.__x)               # 报错: AttributeError: type object 'Dog' has no attribute '__x'
    
    
    '<!--导入方式3-->'
    from super_class import *
    """"是把一个模块中所有函数都导入进来"""
    # print('跨模块访问模块公有属性:', __m)                                   # 报错: NameError: name '__m' is not defined
    # print('跨模块访问模块公有属性:', super_class.__m)                     # 报错:NameError: name 'super_class' is not defined
    # print('跨模块访问模块公有属性:', __n)                                   # 通过__all__属性指定,可以正常访问:跨模块访问模块公有属性: 模块私有化属性__n
    # print('跨模块访问模块公有属性:', super_class.__n)                     # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问类公有属性:', __x)                                    # 报错: NameError: name '__x' is not defined
    # print('跨模块访问类公有属性:', Animal.__x)                             # 报错: NameError: name 'Animal' is not defined
    # print('跨模块访问类公有属性:', super_class.Animal.__x)               # 报错: NameError: name 'super_class' is not defined
    # print('跨模块访问父类公有属性:', Dog.__x)                               # 报错: NameError: name 'Dog' is not defined
    # print('跨模块访问父类公有属性:', super_class.Dog.__x)                 # 报错: NameError: name 'super_class' is not defined
    
    
  • 访问情况
    • 在这里插入图片描述
私有化(隐藏)属性/方法实现机制
  • 名字重整(Name Mangling)机制:重改__x为另一个名称。如:_classname__x
  • 目的:
    • 防止被外界直接访问
    • 防止被子类同名称属性覆盖
  • 名字重整(Name Mangling)机制
    • 1、本质只是一种改名操作

      • 在这里插入图片描述
    • 2、隐藏是对外不对内(在类外部无法调用,在类内部可以直接调用)

      • 改名字在类定义阶段,检查类子代码语法的时候发生,在类调用阶段,用__x去调用就无法调用到了
      • 在这里插入图片描述
    • 3、改名操作,只会在类的定义阶段检查子代码语法的时候执行一次,之后定义的__开头的属性,都不会改名

      • 在这里插入图片描述
私有化属性应用场景
  • 场景1:防止外部直接访问和修改属性值
    class Person:
        # 实例方法,创建实例对象的时候会自动调用这个方法,初始化实例对象
        def __init__(self):
            self.test = '测试'
            self.__age = 18
    
        def setAge(self, num):
            """设置__age属性"""
            self.__age = num
    
        def getAge(self):
            """获取__age属性"""
            return self.__age
    
    
    p = Person()
    # print(p.test)           # 公有属性,可以直接访问
    # print(p.__age)          # 私有属性,不能直接访问,会报错。AttributeError: 'Person' object has no attribute '__age'
    p.__age = 36            # 这并不是修改了实例对象原本的__age属性,而是给实例对象新增了一个__age属性
    # print(p.__dict__)       # {'test': '测试', '_Person__age': 18, '__age': 36},原本的__age属性通过名称重整机制修改为了_Person__age
    
    print(p.getAge())       # 通过指定的方法获取age属性:18
    
    p.setAge(33)            # 通过指定的方法设置age属性
    
    print(p.getAge())       # 通过指定的方法获取age属性:33
    
  • 场景2:对数据进行有效性验证
    class Person:
        # 实例方法,创建实例对象的时候会自动调用这个方法,初始化实例对象
        def __init__(self):
            self.test = '测试'
            self.__age = 18
    
        def setAge(self, num):
            """设置__age属性"""
            if not isinstance(num, int):
                print('请输入一个数字!')
                return
            if not 0 < num < 200:
                print('请输入一个【0-200】之间的数字!')
                return
            self.__age = num
    
        def getAge(self):
            """获取__age属性"""
            return self.__age
    
    
    p = Person()
    # print(p.test)           # 公有属性,可以直接访问
    # print(p.__age)          # 私有属性,不能直接访问,会报错。AttributeError: 'Person' object has no attribute '__age'
    # p.__age = 36            # 这并不是修改了实例对象原本的__age属性,而是给实例对象新增了一个__age属性
    # print(p.__dict__)       # {'test': '测试', '_Person__age': 18, '__age': 36},原本的__age属性通过名称重整机制修改为了_Person__age
    
    print(p.getAge())       # 通过指定的方法获取age属性:18
    
    p.setAge(33)            # 通过指定的方法设置age属性
    
    print(p.getAge())       # 通过指定的方法获取age属性:33
    
    p.setAge('aaa')         # 请输入一个数字!
    
    p.setAge(333)           # 请输入一个【0-200】之间的数字!
    
    print(p.getAge())       # 33
    
    
变量添加下划线规范
  • _x:受保护属性
  • __x:私有属性
  • x_:区别系统关键字(如:class_)
  • __x__:系统内置的,自己定义的时候不要这样写(如:__dict__)

只读属性

概念

  • 一个属性(一般指实例属性),只能读取,不能写入

应用场景

  • 有些属性,只限在内部根据不同场景进行修改,对外界来说,不能修改,只能读取

实现方法

方式一
  • 步骤
    • 1、通过私有化全部隐藏(既不能读,也不能写)
    • 2、通过方法部分公开(公开读的操作)
  • 示例
    class Person:
        def __init__(self):
            self.__age = 18
    
        def getAge(self):
            return self.__age
    
    
    p = Person()
    
    # print(p.__age)          # 报错,通过属性私有化,隐藏了读操作
    # p.__age = 22            # 并不是修改的私有属性,而是新增了__age属性。通过属性私有化,隐藏了写操作
    
    print(p.getAge())       # 通过指定方法,公开读操作
    
  • 存在问题
    • 1、获取属性的时候需要通过调用方法获取p.getAge(),而不是通过属性获取方式获取p.age
    • 2、在外部直接使用赋值p.age = 22 并不会报错(虽然没有修改内部的私有属性,而是给实例添加了一个age属性,但是给人的感觉就是修改了)
  • 优化
    class Person:
        def __init__(self):
            self.__age = 18
    
        # @property的作用:装饰器,可以使用属性的方式调用这个方法
        @property
        def age(self):
            return self.__age
    
    
    p = Person()
    
    print(p.age)        # 18
    # p.age = 22          # 报错,AttributeError: can't set attribute
    
  • 通过优化之后,就可以通过调用属性的方式调用读属性方法了。并且,外部也不能对这个属性方法进行赋值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1137377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt之菜单栏、工具栏、状态栏介绍及工具栏QAction的动态增删显示实现方式

目的 端应用程序或者编辑器基本都支持工具栏快捷功能的动态增删&#xff0c;即通过在菜单栏上打钩就可以在工具栏上看到相应功能的快捷按钮&#xff0c;取消打钩则在工具栏上就移除了该功能的快捷按钮。那么Qt如何实现这个功能&#xff0c;本篇目的就是记录实现此功能的方法及思…

cmd 命令关闭占用端口

工作中还是偶尔会遇到端口号被占用的情况&#xff0c;之前也有写过另一种关闭方式&#xff0c;但是发现没有命令方便&#xff0c;所以记录一下。 1、 查看 8081 端口占用的 pid 。 命令&#xff1a;netstat -ano |findstr 8081 由上图可知&#xff0c;占用 8081 端口的进程 id…

折叠式菜单怎么做编程,初学编程系统化教程初级1上线

中文编程系统化教程&#xff0c;不需英语基础&#xff0c;学习链接——入门篇课程 https://edu.csdn.net/course/detail/39036中文编程系统化教程&#xff0c;不需英语基础&#xff0c;学习链接—— 初级1课程 https://edu.csdn.net/course/detail/39061 ——————————…

C语言输出以下图案

图案&#xff1a; * * * * * * * * * * * * * * * * * * * * * * * * * 完整代码&#xff1a; /* 输出以下图案 * * * * * * * * * * * * * * * * * * * * * * * * * */ #include<stdio.h>int main(){//图案的行数int n5;for (int i 0; i < n; i){//每一行开头空格…

通过profibus PA转Modbus rtu协议网关把RTU数据传到pa设备上

远创智控PA转modbus rtu协议网关YC-PA-485&#xff0c;解决您的协议转换难题。 这款PA转Modbus RTU协议网关&#xff0c;将Profibus PA和Modbus RTU专用通讯协议进行桥接&#xff0c;为您的数据传输提供稳定、高效的解决方案。它符合Modbus通讯协议&#xff0c;允许Modbus设备…

基于Java的学生在线课程学习系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

架构设计基础

一、架构图 二、系统背景 业务发展迅速&#xff0c;积累了大量的数据资产&#xff0c;大数据团队承担数据串联、沉淀&#xff0c;反哺和赋能业务的重要职责。大数据团队协同各部门打造了玩个大狗魔方、大狗宝盒数据产品&#xff0c;提供data-center应用发力数据中台&#xff0…

leetcode做题笔记203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&#xff1a…

redis archive github

https://github.com/redis/redis/releases/tag/7.2.2https://github.com/redis/redis/releases/tag/7.2.2

JS38 高频数据类型

题目来源&#xff1a; 高频数据类型_牛客题霸_牛客网 (nowcoder.com) JS38 高频数据类型 描述 请补全JavaScript代码&#xff0c;要求找到参数数组中出现频次最高的数据类型&#xff0c;并且计算出出现的次数&#xff0c;要求以数组的形式返回。 注意&#xff1a; 1. 基本数据…

【VASP】QVASP 的使用

【VASP】QVASP 的使用 QVASP 的介绍Qvasp 安装使用、测试和算例ELF电荷局域函数计算输入文件简述 QVASP 的介绍 下载地址&#xff1a;https://sourceforge.net/projects/qvasp/ qvasp定位于开发包含VASP输入文件前处理、输出文件后处理的基本功能&#xff0c;同时&#xff0c…

threejs(6)-操控物体实现家居编辑器

// 导入threejs import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; // 导入lil.gui import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";…

使用ControlNet生成视频(Pose2Pose)

目录 ControlNet 介绍 ControlNet 14种模型分别是用来做什么的 ControlNet 运行环境搭建 用到的相关模型地址 ControlNet 介绍 ControlNet 是一种用于控制扩散模型的神经网络结构&#xff0c;可以通过添加额外的条件来实现对图像生成的控制。它通过将神经网络块的权重复制到…

排序-基数排序

排序思路&#xff1a;抽象实现多个桶用来储存所需要排序的基数&#xff0c;再递归的调用到每一次数上&#xff08;通俗点讲&#xff0c;先按个位进行分类&#xff0c;再按十位进行分类&#xff0c;依次排到最高位&#xff0c;最后将所有分类的数连在一起就是排完的序列&#xf…

Pytorch代码入门学习之分类任务(三):定义损失函数与优化器

一、定义损失函数 1.1 代码 criterion nn.CrossEntropyLoss() 1.2 损失函数简介 神经网络的学习通过某个指标表示目前的状态&#xff0c;然后以这个指标为基准&#xff0c;寻找最优的权重参数。神经网络以某个指标为线索寻找最优权重参数&#xff0c;该指标称为损失函数&am…

M1安装python3.12

1.下载pkg文件 Python Releases for macOS | Python.org 2.安装 下一步下一步即可 3.配置环境变量 不配置也可以&#xff0c;直接python3.12即可进入python环境。 4.python3.12改为python 每次少敲4次键盘也挺爽的。效果&#xff1a; 实现步骤&#xff1a; python3.12的默…

DeepinV20实现使用CapsLock键切换输入法

概览 起因参考资料解决问题1. 删除CapsLock键映射关系2. 新建CapsLock键映射关系3. 建立配置文件4. **注销用户或者重启电脑**5. 修改切换输入法快捷键6. 测试输入 起因 看同事的MacBook可以使用CapsLock键切换输入法&#xff0c;而我作为Shift党CapsLock键几乎不使用&#xf…

HackTheBox-Starting Point--Tier 1---Appointment

文章目录 一 题目二 实验过程 一 题目 Tags Web、Databases、Injection、Apache、MariaDB、PHP、SQL、Reconnaissance、SQL Injection译文&#xff1a;Web、数据库、注入、Apache、MariaDB、PHP、SQL、侦察、SQL 注入Connect To attack the target machine, you must be on …

Spring Boot拓展XML格式的请求和响应

在我们开发过程中&#xff0c;我们经常使用的参数绝大多少事HTML和JSON格式的请求和响应处理&#xff0c;但是我们在实际开发过程中&#xff0c;我们可能经历一些&#xff0c;比如对于XML格式的请求&#xff0c;我们在后端应该如何接收&#xff0c;并且如何将XML格式的参数变成…

电源控制系统架构(PCSA)电源控制挑战

安全之安全(security)博客目录导读 下图显示了一个简化的SoC示例&#xff0c;这个例子是从high-level的功能层面来说明的。 该示例以移动设备为中心&#xff0c;但可用于演示在任何SoC配置中高层次的电源管理挑战。 除了示例所示的主要功能(包括处理器、通信功能和公共系统功能…