文章目录
- 1.旧的属性访问方法
- 2.属性访问
1.旧的属性访问方法
- 可以通过点操作符来访问对象属性,也可以通过一些BIF访问类和对象的属性
- 通过property使得x与self.size挂钩,用来通过属性来设置属性
>>> 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 #调用getSize()
10
>>> c.x = 12 #调用x=property(getSize,setSize,delSize)
>>> c.x
12
>>> c.size
12
>>> del c.x #删除属性x()
>>> c.size
Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
c.size
AttributeError: 'C' object has no attribute 'size'
2.属性访问
- 属性相关的魔法方法
魔法方法 | 含义 |
__ getattr__(self, name) | 定义当用户试图获取一个不存在的属性时的行为 |
__ getattribute__(self, name) | 定义当该类的属性被访问时的行为 |
__ setattr__(self, name, value) | 定义当一个属性被设置时的行为 |
__ delattr__(self, value) | 定义当一个属性被删除时的行为 |
- | - |
- 属性魔法方法初学者容易犯死循环如何避免?
第一种:用super()来调用基类,比如:super().__ setattr__(name, value)
第二种:给特殊属性__ dict__赋值,比如:self.__ dict__[name] = value - eg:
##没写,默认继承至object基类
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
- eg:防止死循环陷阱
•写一个矩形类,默认有宽和高两个属性;
•如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时宽和高都应该等于边长。
推荐的重写魔法方法的方式如下:
class Rectangle:
def __init__(self, width=0, height=0):
self.width = width
self.height = height
def __setattr__(self, name, value):#一发生赋值操作r1.square = 10,则会触发__setattr__()魔法方法
if name == 'square':#判断name属性是否为正方形
self.width = value
self.height = value
else:
##防止死循环:self.name = value
super().__setattr__(name, value)
def getArea(self):
return self.width * self.height
>>> r1 = Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square = 10
>>> r1.getArea()
100
- 由于可以用过r1.__dict__获取特殊属性变量,所以代码可以更改为:
class Rectangle:
def __init__(self, width=0, height=0):
self.width = width
self.height = height
def __setattr__(self, name, value):#一发生赋值操作,则会触发__setattr__()魔法方法
if name == 'square':#判断name属性是否为正方形
self.width = value
self.height = value
else:
self.__dict__[name] = value
def getArea(self):
return self.width * self.height
>>> r1 = Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square = 10
>>> r1.getArea()
100
- 参考:小甲鱼零基础入门学习python笔记,第四十五课:魔法方法:属性访问