博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义属性访问
阅读量:4149 次
发布时间:2019-05-25

本文共 2648 字,大约阅读时间需要 8 分钟。

 
客户可直接访问属性(使用点访问运算符);另外,类作者也可为属性指派特殊名称,向客户指明应通过方法来访问属性。现在要讨论的是---定义特殊方法,自定义直接属性访问的行为。
 
Python提供了一系列特殊方法,类可定义这些方法,以控制点访问运算符操纵 类对象的方式。重新定义运算符行为的技术称为“运算符重载”。对点运算符进行重载,相当于综合了前一章所讨论的两种属性访问技术---客户能直接访问属性 (即通过点访问运算符),但这实际是执行访问方法的操作。
 
属性访问自定义方法
方法  说明 
__delattr__  客户删除一个属性时执行(例如 del anObject.attribute) 
__getattr__  客户访问一个属性名,但在对象__dict__属性中找不到这个名称时执行(例如anObject.unfoundName) 
__setattr__  客户将值指派给对象的属性时执行(例如anObject.attribute=value) 
 
Code1

#!/usr/bin/env python

class Time:
        def __init__(self, hour = 0, minute = 0, second = 0):
                self.hour = hour
                self.minute = minute
                self.second = second
        def __setattr__(self, name, value):
                if name == "hour":
                        if 0 <= value < 24:
                                self.__dict__["_hour"] = value
                        else:
                                raise ValueError, "Invalid hour value: %d" % value
                elif name == "minute" or name == "second":
                        if 0 <= value < 60:
                                self.__dict__["_" + name] = value
                        else:
                                raise ValueError, "Invalid % value: %d" % (name, value)
                else:
                        self.__dict__[name] = value
        def __getattr__(self, name):
                if name == "hour":
                        return self._hour
                elif name == "minute":
                        return self._minute
                elif name == "second":
                        return self._second
                else:
                        raise AttributeError, name
        def __str__(self):
                return "%.2d:%.2d:%.2d" % (self._hour, self._minute, self._second)

新的定义通过特殊方法__getattr__和__setattr__来控制客户访问及修改对象属性的 方式。__init__为Time类默认的构造函数。构造函数只是将参数值指派给新对象的属性。如果类定义了特殊方法__setattr__,程序每次通 过点运算符为对象的属性指派值时,Python都会调用这个方法。

这里__setattr__方法包含查错代码,用于确保对象数据处于一致性状态。方法要接收3个参数: 对象引用(self)、要设置的属性名以及要指派给属性的值。首先检测要设置的属性是否名叫"hour",如果是,则判断指定的值是否在正确的范围内,如 果值在正确的范围内,则访问对象的__dict__属性中恰当的键-值对,将值指派给属性_hour;否则,将引发一个异常,指出值是无效的。

非常重要的一点在于,__setattr__方法要用对象的__dict__属性来设置对象的属性。如果使用如下语句:

self._hour = value

那么__setattr__方法会再次执行,并使用参数"_hour"和value,从而导致无穷递归。相反,通过对象的__dict__属性来指派值,就不是调用__setattr__方法,而是将相应的键-值对插入对象的__dict__。

Print1

[root@lvdbing tmp]# python

Python 2.5.2 (r252:60911, Sep 20 2008, 02:27:16)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from TimeAccess import Time
>>> time1 = Time(20, 20, 20)
>>> print time1
20:20:20
>>> print time1.hour, time1.minute, time1.second
20 20 20
>>> time1.hour = 10
>>> print time1
10:20:20
>>> time1.minute = 61
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "TimeAccess.py", line 23, in __setattr__
    raise ValueError, "Invalid % value: %d" % (name, value)
ValueError: unsupported format character 'v' (0x76) at index 10


假如客户程序包含以下表达式:

time1.attribute

并将其作为一个"右值"(运算符右边的值),Python首先会在time1的__dict__属性中查找指定的属性名。如果找到这个名称,Python将返回属性的值。如果在对象的__dict__中没有找到属性名,Python会生成以下调用:

time1.__getattr__(attribute)

其中的attribute是客户试图访问的属性名。方法会检测客户是否试图访问hour,minute或者second。如果是,就返回相应属性的值。否则,方法会引用一个异常。

转载地址:http://mrsti.baihongyu.com/

你可能感兴趣的文章
流形学习-高维数据的降维与可视化
查看>>
Python-OpenCV人脸检测(代码)
查看>>
python+opencv之视频人脸识别
查看>>
人脸识别(OpenCV+Python)
查看>>
6个强大的AngularJS扩展应用
查看>>
网站用户登录系统设计——jsGen实现版
查看>>
第三方SDK:讯飞语音听写
查看>>
第三方SDK:JPush SDK Eclipse
查看>>
第三方开源库:imageLoader的使用
查看>>
自定义控件:飞入飞出的效果
查看>>
自定义控件:动态获取控件的高
查看>>
第三方开源库:nineoldandroid:ValueAnimator 动态设置textview的高
查看>>
第三方SDK:百度地图SDK的使用
查看>>
Android studio_迁移Eclipse项目到Android studio
查看>>
JavaScript setTimeout() clearTimeout() 方法
查看>>
CSS border 属性及用border画各种图形
查看>>
转载知乎-前端汇总资源
查看>>
JavaScript substr() 方法
查看>>
JavaScript slice() 方法
查看>>
JavaScript substring() 方法
查看>>