访问限制(关于下划线)

一、下划线的几种常见出现形式

python中变量属性方法得命名中经常会出现下划线,并且不同的下划线形式还有不同的含义,掌握其代表的不同含义,对于理解python代码来说也是很有帮助的。先来看一段代码:

class Member(object):

    def __init__(self, card_id, name,  birth ):
        self.__card_id = card_id
        self._name = name
        self.birth = birth
       
    def print_info(self):
        print('%s(%s): %d' % (self.__card_id,self._name, self.birth))

s1=Member("1101","张三","0901")
print(s1._name)   #张三  
print(s1.birth)   #0901
print(s1.__card_id)   
#AttributeError: 'Student' object has no attribute 'name'

运行上述代码会发现,无法输出s1.__card_id这个属性了,而s1._name和s1.birth是可以输出的,这就涉及到下划线在python中的特殊作用了。
在Member内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据。
但是,有时候类的内部属性不想在外部被访问,比如Menber类中,其属性__card_id(此属性名中间的下划线是隔开单词的作用,是一种常见的python命名规则)以双下划线开头,在Python中,实例的变量名如果以__双下划线开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,就可以保护属性__card_id不被随意调用和更改,这样通过访问限制的保护,代码更加健壮。

归纳以下下划线的几种形式和作用:

  1. 以双下划线开头的变量属性和方法:受保护的对象,不能访问不能调用。
  2. 变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量。
  3. 以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
  4. 只要开头没有下划线,放在其他任何地方都没有任何特殊用法和含义,如:card_id , card__id , cardid_ , cardid__等,爱咋咋地,你喜欢就好。

然后呢,又来找事,就是偏要访问以双下划线开头的变量咋弄,可以啊,给你访问啊,但是你不要像上面那样直接啊,看这里:

print(s1._Member__card_id)   

不能直接访问__card_id是因为Python解释器对外把__card_id变量改成了_Member__name,所以,仍然可以通过_Member__card_id来访问__card_id变量。
但是呢,这么干有风险,因为不同版本的Python解释器可能会把__card _id改成不同的变量名。

二、通过访问器方法访问私有变量

class Member(object):

    def __init__(self, card_id, name, birth):
        self.__card_id = card_id
        self._name = name
        self.birth = birth
       
    def print_info(self):
        print('%s(%s): %d' % (self.__card_id,self._name, self.birth))
    
    def get_cardid(self):
        return self.__card_id
    
    def set_cardid(self,cardid):
        if len(cardid) != len(self.__card_id):
            raise ValueError('卡号长度不能变') #避免传入不合理的参数
        self.__card_id = cardid
        
s1=Member("1101","张三","0901")
s1.get_cardid()
s1.set_cardid("1001")   #重新设置卡号
s1.set_cardid("1000001")  #会报错:卡号长度不能变

在Member类中定义了两个方法,get_cardid和set_cardid,通过这两个函数达到访问属性__card_id和重新设置__card_id的取值,在set_cardid函数中还加入了控制逻辑:卡号长度设置不合理时会报错,可以对参数做检查,避免传入不合理的参数。
将私有变量的访问和赋值通过构造方法来实现,看似是将简单的问题变复杂了,实际是保护对象内部的状态不被随意修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值