Python高级特性:私有属性

简介

在其它高级编程语言,如Java、C++等,均支持对属性和函数的访问控制,如public, private等关键字;也许你会好奇在Python语言是否支持数据隐藏功能呢。本文结合实际案例,来介绍Python编程语言中如何实现私有属性和私有函数,实现数据隐藏的。

私有属性和私有函数例子

先看一下下面的简单例子:
class Example(object):
    def __init__(self):
        self.__data = 88   #private attribute
        
    def __inc(self):       #private function
        self.__data += 1
        
    def get_data(self):
        self.__inc()
        
        return self.__data
        
    def __str__(self):
        return '%d' % self.__data


if __name__ == '__main__':
    example = Example()
    
    print("Access the private function:")
    try:
        example.__inc()
    except AttributeError as e:
        print(e)
    
    print("Access the private attribute:")
    try:
        print(example.__data)
    except AttributeError as e:
        print(e)
        
    print(example.get_data())
在Example类中定义了私有属性__data,并在构造器里将它初始化为88。定义了私有函数__inc()用于将私有属性__data增1。观察系统运行结果:
Access the private function:
'Example' object has no attribute '__inc'
Access the private attribute:
'Example' object has no attribute '__data'
89
在访问私有属性和私有函数都被抛出了AttributeError异常,意味着Example对象中没有相应的属性。从上面的运行的例子中我们确实看到,在属性和函数的开始出加两个下划线,就可以达到私有化的目的。

私有属性本质

Python支持变量名压缩(mangling)的概念,让类内部某些属性和函数局部化,使得“无法”访问从外部访问。其工作方式是在class语句内开头有两个下滑线,但结尾没有两个下划线的变量名,会自动进行扩展,从而包含所在类的名称。为了直观的了解变量压缩的概念,我们看一下上面的例子中,example实例属性实际的样子,使用内置函数dir()来查看:
>>> dir(example)
['_Example__data', '_Example__inc', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', 
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', 
'__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
 '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_data']
你会发现,实际上example实例的属性中,并不包含__data和__inc两个属性,而是被扩展成了_Example__data和_Example__inc。这就是Python的变量名压缩机制,本质其实只是一种把类所创建的变量名局部化的方式,但名称压缩并无法阻止类外部代码对它的访问:你可以通过_Example__data和_Example__inc来访问相应的属性,没有办法来阻止你。所以,我们可以称这种私有属性为伪私有属性。

为什么使用伪私有属性

为私有属性功能是为了缓和与实例属性存储方式有关的问题。在Python中,所有实例的属性都会在类树底部的单个实例对象中。在Python的类方法中,每当方法赋值self的属性时(如self.attr = value),就会在该实例内修改或创建该属性(继承搜索只发生在引用时,而不是赋值时)。即使在这个层次中有多个相同的类赋值属性,也是如此。因此有可能发生冲突。
伪私有属性在较大的框架和工具中非常有用,既避免引入可能在类树中某处偶然隐藏定义的新的方法名,也可以减少内部方法被树的较低处的名称替代的机会。如果一个属性或方法倾向于只在一个类中使用,在前面使用双下划线,一确保不受到继承树中其它名称的干扰,尤其是在多继承的环境中。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值