类属性访问限制的知识点

问题描述:

类属性访问限制的知识点

第一段代码
class Swan:
    '''天鹅类'''
    _neck_swan="天鹅的脖子很长"                  #定义私有属性
    def __init__(self):
        print("__init__():",Swan._neck_swan)     #在实例方法中访问私有属性
swan=Swan()                                      #创建Swan类的实例
print("直接访问:",swan._neck_swan)               #保护属性可以通过实例名访问

#输出结果如下。
#__init__(): 天鹅的脖子很长
#直接访问: 天鹅的脖子很长

第一段代码结果:
__init__(): 天鹅的脖子很长
直接访问: 天鹅的脖子很长


第二段代码如下:
class Swan:
    '''天鹅类'''
    _neck_swan="天鹅的脖子很长"                  #定义私有属性
    def __init__(self):
        print("__init__():",Swan._neck_swan)     #在实例方法中访问私有属性
swan=Swan()                                      #创建Swan类的实例
print("直接访问:",swan._neck_swan)               #保护属性可以通过实例名访问

#输出结果如下。
#__init__(): 天鹅的脖子很长
#直接访问: 天鹅的脖子很长

第二段代码结果如下:
__init__(): 天鹅的脖子很长
加入类名: 天鹅的脖子很长
Traceback (most recent call last):
  File "C:/Users/86178/AppData/Local/Programs/Python/Python312/siyoushuxing2.py", line 8, in <module>
    print("直接访问:",swan.__neck_swan)           #私有属性不能通过实例名访问
AttributeError: 'Swan' object has no attribute '__neck_swan'. Did you mean: '_Swan__neck_swan'?


上述代码的结果总结如下:
访问限制这个知识点,针对类属性的定义。首先,单下划线+属性表示这个属性只能被类本身和实例化对象访问,不能被from module import *访问。其次,双下划线+属性只能被类本身进行访问,不能通过实例化对象访问,如果想通过实例化对象访问,则使用类的实例名._类名__属性名访问。

问题解答:

关于属性访问控制的知识点如下:

  1. 单下划线 _

    • 单下划线前缀属性(例如 _neck_swan)是受保护的属性。根据惯例,它表示这个属性不应该被直接访问(虽然技术上还是可以访问的)。
    • 它可以通过类本身和实例化对象直接访问,但不建议在外部代码中直接使用。
    • 使用 from module import * 时,带有单下划线前缀的属性不会被导入。
  2. 双下划线 __

    • 双下划线前缀属性(例如 __neck_swan)是私有的属性。这种属性不能在类的外部直接访问。
    • 双下划线前缀会触发名称改写(name mangling),即 Python 会将其改为 _类名__属性名 的形式。
    • 只能通过 实例名._类名__属性名 的方式访问。

以下是对比两个代码段的细节解释:

第一段代码:

class Swan:
    '''天鹅类'''
    _neck_swan = "天鹅的脖子很长"  # 定义保护属性
    def __init__(self):
        print("__init__():", Swan._neck_swan)  # 在实例方法中访问保护属性

swan = Swan()  # 创建Swan类的实例
print("直接访问:", swan._neck_swan)  # 保护属性可以通过实例名访问
输出结果:
__init__(): 天鹅的脖子很长
直接访问: 天鹅的脖子很长

第二段代码:

class Swan:
    '''天鹅类'''
    __neck_swan = "天鹅的脖子很长"  # 定义私有属性
    def __init__(self):
        print("__init__():", Swan.__neck_swan)  # 在实例方法中访问私有属性

swan = Swan()  # 创建Swan类的实例
print("直接访问:", swan.__neck_swan)  # 私有属性不能通过实例名访问
输出结果:
__init__(): 天鹅的脖子很长
Traceback (most recent call last):
  File "C:/Users/86178/AppData/Local/Programs/Python/Python312/siyoushuxing2.py", line 8, in <module>
    print("直接访问:", swan.__neck_swan)  # 私有属性不能通过实例名访问
AttributeError: 'Swan' object has no attribute '__neck_swan'. Did you mean: '_Swan__neck_swan'?

结论:

  • 第一段代码中的 _neck_swan 是保护属性,可以在类内部和通过实例直接访问。
  • 第二段代码中的 __neck_swan 是私有属性,通过实例直接访问会导致 AttributeError。如果需要访问,可以使用 swan._Swan__neck_swan

总结你的理解:

  • 保护属性(单下划线):只能被类本身和实例对象访问,不能被 from module import * 导入。
  • 私有属性(双下划线):只能被类本身访问,不能通过实例直接访问,如果需要访问,则使用 实例名._类名__属性名 这种改写后的名称访问。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神笔馬良

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值