课时45:魔法方法:属性访问
2018-08-26 17:32:43来源:博客园 阅读 ()
目录:
一、属性访问
二、课时45课后习题及答案
****************
一、属性访问
****************
通常可以通过(.)操作符的形式去访问对象的属性,在类与对象这一章的最后一节也有谈到如何通过几个BIF适当地去访问属性:
>>> class C: def __init__(self): self.x = 'X-man' >>> c = C() >>> c.x 'X-man' >>> getattr(c,'x','木有这个属性') 'X-man' >>> getattr(c,'y','木有这个属性') '木有这个属性' >>> setattr(c,'y','Yellow') >>> getattr(c,'y','木有这个属性') 'Yellow' >>> delattr(c,'x') >>> c.x Traceback (most recent call last): File "<pyshell#11>", line 1, in <module> c.x AttributeError: 'C' object has no attribute 'x'
然后还介绍了一个叫做property()函数的用法,这个property()使得我们可以用属性去访问属性:
>>> class C: def __init__(self,size = 10): self.size = size def getSize(self): return self.size def setSize(self,value): self.size = value def delSize(self): del self.size x = property(getSize,setSize,delSize) >>> c = C() >>> c.x 10 >>> c.x = 12 >>> c.x 12 >>> c.size 12 >>> del c.x >>> c.size Traceback (most recent call last): File "<pyshell#29>", line 1, in <module> c.size AttributeError: 'C' object has no attribute 'size'
那么关于属性访问,肯定也有相应得魔法方法来管理。通过对这些魔法方法的重写,可以随心所欲的控制对象的属性访问。
下表列举了属性相关的魔法方法。
__getattr__(self, name) 定义当用户试图获取一个不存在的属性时的行为 __getattribute__(self, name) 定义当该类的属性被访问时的行为 __setattr__(self, name, value) 定义当一个属性被设置时的行为 __delattr__(self, name) 定义当一个属性被删除时的行为
做个小测试:
class C: def __getattribute__(self, name): print('getattribute') # 使用 super() 调用 object 基类的 __getattribute__ 方法 return super().__getattribute__(name) def __setattr__(self, name, value): print('setattr') super().__setattr__(name, value) def __delattr__(self, name): print('delattr') super().__delattr__(name) def __getattr__(self, name): print('getattr')
>>> c = C() >>> c.x getattribute getattr >>> c.x = 1 setattr >>> c.x getattribute 1 >>> del c.x delattr >>> setattr(c,'y','Yellow') setattr
这几个魔法方法在使用上需要注意的是,有一个死循环的陷阱,初学者很容易中招,通过一个实例来讲解。
写一个矩形类,默认有宽和高两个属性;
如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时宽和高都应该等于边长。
class Rectangle: def __init__(self, width=0, height=0): self.width = width self.height = height def __setattr__(self, name, value): if name == 'square': self.width = value self.height = value else: self.name = value def getArea(self): return self.width * self.height
>>> r1 = Rectangle(4,5) Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> r1 = Rectangle(4,5) File "C:\Users\14158\Desktop\lalallalalal.py", line 3, in __init__ self.width = width File "C:\Users\14158\Desktop\lalallalalal.py", line 11, in __setattr__ self.name = value File "C:\Users\14158\Desktop\lalallalalal.py", line 11, in __setattr__ self.name = value File "C:\Users\14158\Desktop\lalallalalal.py", line 11, in __setattr__ self.name = value [Previous line repeated 987 more times] File "C:\Users\14158\Desktop\lalallalalal.py", line 7, in __setattr__ if name == 'square': RecursionError: maximum recursion depth exceeded in comparison
这是为什么呢?
分析一下:实例化对象,调用__init__()方法,在这里self.width和self.heigth分别初始化赋值。一发生赋值操作,就会自动触发__setattr__()魔法方法,width和height两个属性被赋值,于是执行else的下边的语句,就变成了self.width = value,那么就相当于又触发了__setattr__(),那么这样就依赖基类的方法来实现赋值:
else: super().__setattr__(name,value)
>>> r1 = Rectangle(4,5) >>> r1.getArea() 20 >>> r1.square = 10 >>> r1.getArea() 100
另一种方法就是给特殊属性__dict__赋值。对象有一个特殊属性,叫做__dict__,它的作用是以字典的形式显示出当前对象的所有属性以及相对应的值:
else: self.__dict__[name] = value
运行结果一样。
*******************************
二、课时45课后习题及答案
*******************************
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python_字符串方法 2019-08-13
- python_公共方法 2019-08-13
- python3 之 判断闰年小实例 2019-08-13
- pycharm查看函数用法,参数信息的设置方法 2019-07-24
- Python多进程方式抓取基金网站内容的方法分析 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash