在面向对象编程中,公开的数据成员可以在外部随意访问和修改,很难控制用户修改时新数据的合法性。解决这一问题的常用方法是定义私有数据成员,然后设计公开的成员方法来提供对私有数据成员的读取和修改操作,修改私有数据成员时可以对值进行合法性检查,提高了程序的健壮性,保证了数据的完整性。属性结合了公开数据成员和成员方法的优点,既可以像成员方法那样对值进行必要的检查,又可以像数据成员一样灵活的访问。

Python 2.x中属性的实现有很多不如人意的地方,在Python 3.x中,属性得到了较为完整的实现,支持更加全面的保护机制。如果设置属性为只读,则无法修改其值,也无法为对象增加与属性同名的新成员,同时,也无法删除对象属性。例如:

>>> class Test:

    def __init__(self, value):

        self.__value = value  #私有数据成员

    @property  #修饰器,定义属性,提供对私有数据成员的访问

    def value(self):   #只读属性,无法修改和删除

        return self.__value

>>> t = Test(3)

>>> t.value

3

>>> t.value = 5   #只读属性不允许修改值

Traceback (most recent call last):

  File "<pyshell#151>", line 1, in <module>

    t.value = 5

AttributeError: can't set attribute

>>> t.v=5   #动态增加新成员

>>> t.v

5

>>> del t.v #动态删除成员

>>> del t.value  #试图删除对象属性,失败

Traceback (most recent call last):

  File "<pyshell#152>", line 1, in <module>

    del t.value

AttributeError: can't delete attribute

>>> t.value

3

下面的代码则把属性设置为可读、可修改,而不允许删除。

>>> class Test:

    def __init__(self, value):

        self.__value = value    

    def __get(self):   #读取私有数据成员的值

        return self.__value

    def __set(self, v): #修改私有数据成员的值

        self.__value = v

    value = property(__get, __set)  #可读可写属性,指定相应的读写方法

    def show(self):

        print(self.__value)

>>> t = Test(3)

>>> t.value #允许读取属性值

3

>>> t.value = 5   #允许修改属性值

>>> t.value

5

>>> t.show()  #属性对应的私有变量也得到了相应的修改

5

>>> del t.value  #试图删除属性,失败

Traceback (most recent call last):

  File "<pyshell#152>", line 1, in <module>

    del t.value

AttributeError: can't delete attribute

当然,也可以将属性设置为可读、可修改、可删除。

>>> class Test:

    def __init__(self, value):

        self.__value = value

    def __get(self):

        return self.__value

    def __set(self, v):

        self.__value = v

    def __del(self):   #删除对象的私有数据成员

        del self.__value

    value = property(__get, __set, __del)   #可读、可写、可删除的属性

    def show(self):

        print(self.__value)

>>> t = Test(3)

>>> t.show()

3

>>> t.value

3

>>> t.value = 5

>>> t.show()

5

>>> t.value

5

>>> del t.value

>>> t.value  #相应的私有数据成员已删除,访问失败

Traceback (most recent call last):

  File "<pyshell#165>", line 1, in <module>

    t.value

  File "<pyshell#157>", line 6, in __get

    return self.__value

AttributeError: 'Test' object has no attribute '_Test__value'

>>> t.show()

Traceback (most recent call last):

  File "<pyshell#166>", line 1, in <module>

    t.show()

  File "<pyshell#157>", line 17, in show

    print(self.__value)

AttributeError: 'Test' object has no attribute '_Test__value'

>>> t.value =1  #为对象动态增加属性和对应的私有数据成员

>>> t.show()

1

>>> t.value

1

稿源:微信定制开发www1.qixoo.com

详解Python对象属性的更多相关文章

  1. 详解Python中内置的NotImplemented类型的用法

    它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...

  2. 详解python的装饰器decorator

    装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...

  3. 详解 Python 的二元算术运算,为什么说减法只是语法糖?

    原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...

  4. dom对象详解--document对象(二)

       dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...

  5. dom对象详解--document对象(一)

     document对象 Document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学习好dom编程的关键所在. Document对象是window对象的一 ...

  6. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  7. Struts功能详解——ActionMapping对象

    Struts功能详解——ActionMapping对象 ActionMapping描述了struts中用户请求路径和Action的映射关系,在struts中每个ActionMapping都是通过pat ...

  8. php开发面试题---php面向对象详解(对象的主要三个特性)

    php开发面试题---php面向对象详解(对象的主要三个特性) 一.总结 一句话总结: 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为. 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸 ...

  9. 详解Python编程中基本的数学计算使用

    详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...

随机推荐

  1. f2fs解析(四)f2fs的extent特性

    extent的意思是“程度”,但是我还是搞不清楚要如何把“程度”和我理解的extent联系到一起. 文件的偏移和page-cache的映射关系体现在address space 中的一颗基数树上:当基数 ...

  2. 14Mybatis_输入映射(传递pojo的包装对象)——很重要

    假设我们有这么一个需求:用户信息的综合查询,需要传入的查询条件很复杂(可能包括用户信息,其他的信息,比如商品,订单) 我们的思想是:传入到select中的parameterType是一个包装类,里面可 ...

  3. 课题:如何培养自己的SEO资源

    课题:如何培养自己的SEO资源 问:做SEO最重要的是什么?[针对性的流量]答:看获取一样东西的门槛.稀缺性,人人可得价值不大外链 内容 流量[正确]针对性的自然流量是用户自愿带来的,价值高,能形成购 ...

  4. 史上最全Html与CSS布局技巧

    单列布局水平居中水平居中的页面布局中最为常见的一种布局形式,多出现于标题,以及内容区域的组织形式,下面介绍四种实现水平居中的方法(注:下面各个实例中实现的是child元素的对齐操作,child元素的父 ...

  5. Web API 实现JSONP或者安装配置Cors跨域

    前言 照理来说本节也应该讲Web API原理,目前已经探讨完了比较底层的Web API消息处理管道以及Web Host寄宿管道,接下来应该要触及控制器.Action方法,以及过滤器.模型绑定等等,想想 ...

  6. 封印术:shadow dom

    置顶文章:<纯CSS打造银色MacBook Air(完整版)> 上一篇:<鼠标滚动插件smoovejs和wowjs> 作者主页:myvin 博主QQ:851399101(点击Q ...

  7. redis async client 与自有框架集成

    hiredis的异步接口已经支持ae libuv libev 和 libevent集成,具体头文件可以参见redis/deps/hiredis/adapters,样例参见redis/deps/hire ...

  8. Scala之Map,Tuple

    /** * 1,默认情况下Map构造的是不可变的集合,里面的内容不可修改,一旦修改就变成新的Map,原有的Map内容保持不变: * 2,Map的实例是调用工厂方法模式apply来构造Map实例,而需要 ...

  9. 你应当如何学习C++(以及编程)(转载)

    你应当如何学习C++(以及编程)(rev#1) By 刘未鹏(pongba) C++的罗浮宫(http://blog.csdn.net/pongba) Javascript是世界上最受误解的语言,其实 ...

  10. 深入学习JavaScript(一)

    1.全局变量与局部变量 全局变量:全局变量就是在函数的外部定义的一个在其他地方都可以调用的变量 局部变量:局部变量是相对于全局变量而言的,局部变量指的是在一个区域内存在这个变量 全局变量的创建原理是在 ...