通常可以通过点(.)操作符的形式去访问对象的属性,也可以通过BIF适当地去访问属性,看个例子吧

>>> class A():
def __init__(self):
self.x = 'XYZ-xyz' >>> a = A()
>>> a.x
'XYZ-xyz'
>>> getattr(a,'x','没有这个属性')
'XYZ-xyz'
>>> getattr(a,'z','没有这个属性')
'没有这个属性'
>>> setattr(a,'z','red')
>>> getattr(a,'z','red')
'red'
>>> delattr(a,'x')
>>> a.x
Traceback (most recent call last):
File "<pyshell#12>", line , in <module>
a.x
AttributeError: 'A' 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#30>", line 1, in <module>
c.size
AttributeError: 'C' object has no attribute 'size'

关于属性访问,肯定也有相应的魔法方法来管理。通过对这些魔法方法的重写,照样可以随心所欲控制对象的属性访问。

来介绍下属性相关的魔法方法:

魔法方法 含义
__getattr__(self,name) 定义当用户试图获取一个不存在的属性十的行为
__getattribute__(self,name) 定义当该类的属性被访问时的行为
__setattr__(self,name) 定义当一个属性被设置时的行为
__delattr__(self,name) 定义当一个属性被删除时的行为

好了,我们先来做个测试:

>>> class A():
def __getattribute__(self,name):
print('getattribute')
#使用super()调用object基类__getattribut__()方法
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') >>> a = A()
>>> a.x
getattribute
getattr
>>> a.x = 1
setattr
>>> a.x
getattribute
1
>>> del a.x
delattr
>>> setattr(a,'y','yellow')
setattr

这几个魔法方法在使用的时候要注意,防止进入死循环陷阱,下面通过实例来说明,写一个矩形类(Rectangle),默认有宽(width)和高(height)两个属性;如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时高宽都应该等于边长

>>> class Rectangle():
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self,key,value):
if key == 'square':
self.width = value
self.height = value
else:
self.key = value
def getArea(self):
return self.width *self.height >>> r1 = Rectangle(4,5)
Traceback (most recent call last):
File "<pyshell#65>", line 1, in <module> r1 = Rectangle(4,5)
File "<pyshell#64>", line 3, in __init__ self.width = width
File "<pyshell#64>", line 10, in __setattr__ self.key = value
File "<pyshell#64>", line 10, in __setattr__ self.key = value
File "<pyshell#64>", line 10, in __setattr__ self.key = value
[Previous line repeated 325 more times]
File "<pyshell#64>", line 6, in __setattr__ if key == 'square':
RecursionError: maximum recursion depth exceeded in comparison

出现这个循环的原因在于调用了__init__()方法,在这里给self.width和self.height分别初始化赋值。一旦发生赋值操作就会自动触发__setattr__()魔法方法,width和height两个属性被赋值,于是执行了else的下边的语句,就又变成了self.width=value,那么久相当于又触发了__setattr__()魔法方法,造成了死循环。

解决方法一,就是和刚才的一样,使用super()来调用基类的__setattr__(),那么这样就依赖基类的方法来实现赋值:

>>> class Rectangle():
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self,key,value):
if key == 'square':
self.width = value
self.height = value
else:
super().__setattr__(key,value)
def getArea(self):
return self.width *self.height >>> r1 = Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square = 10
>>> r1.getArea()
100

解决方法二:给特殊属性__dict__赋值。对象有一个特殊的属性,__dict__,它的作用是以字典的形式显示出当前对象的所有属性以及相对于的值。

调用死循环的类

>>> r1.__dict__
{'width': 10, 'height': 10}
>>> class Rectangle():
def __init__(self,width = 0,height = 0):
self.width = width
self.height = height
def __setattr__(self,key,value):
if key == 'square':
self.width = value
self.height = value
     else:
       self.__dict__[name] = value

>>> r1 = Rectangle(4,5)

python_魔法方法(四):属性访问的更多相关文章

  1. Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )

    通常情况下,我们在访问类或者实例对象的时候,会牵扯到一些属性访问的魔法方法,主要包括: ① __getattr__(self, name): 访问不存在的属性时调用 ② __getattribute_ ...

  2. 零基础学习python_魔法方法(41-48课)(迭代器)

    接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...

  3. 【python学习笔记】9.魔法方法、属性和迭代器

    [python学习笔记]9.魔法方法.属性和迭代器 魔法方法:xx, 收尾各有两个下划线的方法 __init__(self): 构造方法,创建对象时候自动执行,可以为其增加参数, 父类构造方法不会被自 ...

  4. ie8 报错:意外地调用了方法或属性访问

    在某场景中一句简单的js: $("#changeOption").text("增加"); 在 IE8 下面报错:'意外地调用了方法或属性访问' 改成:$(&qu ...

  5. python基础教程_学习笔记11:魔法方法、属性和迭代器

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/signjing/article/details/31417309 魔法方法.属性和迭代器 在pyth ...

  6. python学习笔记之七:魔法方法,属性

    在python中,有的名称会在前面和后面加上两个下划线,由这些名字组成的集合所包含的方法称为魔法方法(或者是特殊方法).如果对象实现了这些方法中的某一个,那么这个方法会在特殊的情况下(确切地说是根据名 ...

  7. 《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器

    准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here ...

  8. 【Python045-魔法方法:属性访问】

    一.属性的几种访问方式 1.类.属性名 >>> class C: def __init__(self): self.x = 'X-man' >>> c = C() ...

  9. python_魔法方法(五):描述符和定制序列

    描述符(property的原理) 描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性.那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__(). ...

随机推荐

  1. [转]七个对我最好的职业建议(精简版)--Nicholas C. Zakas

    一.不要别人点什么,就做什么 我的第一份工作,只干了8个月,那家公司就倒闭了.我问经理,接下来我该怎么办,他说: "小伙子,千万不要当一个被人点菜的厨师,别人点什么,你就烧什么.不要接受那样 ...

  2. SQL Server:sp_send_dbmail参数设置

    sp_send_dbmail [ [ @profile_name = ] 'profile_name' ]    [ , [ @recipients = ] 'recipients [ ; n ]'  ...

  3. 【转】Pro Android学习笔记(四六):Dialog(3):对话框弹对话框

    目录(?)[-] 帮助提示框的实现 实现再弹框 再谈fragment管理器 提示框的按钮Help,将触发弹出新的帮助提示框. 帮助提示框的实现 帮助提示框的实现很简单,利用重写onCreateView ...

  4. js---数组习题---

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Python-socket发送文件并解决粘包问题

    服务器端要先根据客户端要下载的文件进行判断是否存在,还要根据文件大小来进行传送,最后还要比对文件的md5值来判断传送的文件是否正确,通过判断剩余字节来解决粘包问题 服务器端 # -*- coding: ...

  6. Python函数(十二)-迭代器

    字符串,列表,元组,字典,集合,生成器这些能通过for循环来遍历的数据类型都是可迭代对象 可通过isinstance判断是不是可迭代对象 >>> from collections i ...

  7. electron将网站打包成桌面应用

    需求同 NW.js将网站打包成桌面应用 1. 从github上克隆electron示例项目 git clone https://github.com/electron/electron-quick-s ...

  8. javascript之系统对话框

    浏览器通过alert(),confirm()和prompt()方法调用系统对话框,向用户显示信息. alert()接受一个字符串并显示给用户,结果是显示一个对话框,其中包括指定的文本和一个OK(“确定 ...

  9. CountDownLatch分析

    1 什么是CountDownLatch呢? 先看看官网的定义 :一种同步帮助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成. 现在由我来解释什么是CountDownLatch吧:比如说我 ...

  10. 《精通Spring4.X企业应用开发实战》读后感第六章(内部工作机制、BeanDefinition、InstantiationStrategy、BeanWrapper)