0
点赞
收藏
分享

微信扫一扫

(P45)魔法方法:旧的属性访问方法,属性访问


文章目录

  • ​​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笔记​​,​​第四十五课:魔法方法:属性访问​​


举报

相关推荐

0 条评论