page contents

setattr,getattr,delattr函数使用详解?

轩辕小不懂 发布于 2021-11-10 14:09
阅读 552
收藏 0
分类:人工智能
2378
Nen
Nen
- 程序员

1.setattr(self,name,value):如果想要给 name 赋值的话,就需要调用这个方法。

2.getattr(self,name):如果 name 被访问且它又不存在,那么这个方法将被调用。

3.delattr(self,name):如果要删除 name 的话,这个方法就要被调用了。

下面我们用例子来演示一下:

>>> class Sample:

...    def __getattr__(self,name):

...            print('hello getattr')

...    def __setattr__(self,name,value):

...            print('hello setattr')

...            self.__dict__[name] = value

...

Python

上面的例子中类 Sample 只有两个方法,下面让我们实例化一下:


>>> s = Sample()

>>> s.x

hello getattr

Python

s.x 这个实例属性本来是不存在的,但是由于类中有了 getattr(self,name) 方法,当发现属性 x 不存在于对象的 dict 中时,就调用了 getattr,也就是所谓的「拦截成员」。


>>> s.x = 7

hello setattr

Python

同理,给对象的属性赋值的时候,调用了 setattr(self,name,value) 方法,这个方法中有 self.dict[name] = value,通过这个就将属性和数据存到了对象 dict 中。如果再调用这个属性的话,会成为下面这样:


>>> s.x

7

Python

出现这种结果的原因是它已经存在于对象的 dict 中了。


看了上面的两个,你是不是觉得上面的方法很有魔力呢?这就是「黑魔法」,但是它具体有什么应用呢?我们接着来看:

class Rectangle:

   """

   the width and length of Rectangle

   """


   def __init__(self):

       self.width = 0

       self.length = 0


   def setSize(self,size):

       self.width, self.length = size


   def getSize(self):

       return self.width, self.length


if __name__ = = "__main__":

   r = Rectangle()

   r.width = 3

   r.length = 4

   print(r.getSize())

   print(r.setSize((30,40)))

   print(r.width)

   print(r.length)

Python

上面是我根据一个很有名的例子改编的,你可以先想一下结果,想完以后可以接着往下看:

(3, 4)

30

40

Python

这段代码运行的结果如上面所示,作为一个强迫证的码农,对于这种可以改进的程序当然不能容忍。我们在上面介绍的特殊方法,我们一定要学以致用,虽然重新写的不一定比原来的好,但我们还是要尝试去用:

class NewRectangle:

   """

   the width and length of Rectangle

   """


   def __init__(self):

       self.width = 0

       self.length = 0


   def __setattr__(self, name, value):

       if name = = 'size':

           self.width, self.length = value

       else:

           self.__dict__[name] = value


   def __getattr__(self, name):

       if name = = 'size':

           return self.width, self.length

       else:

           return AttributeError


if __name__ == "__main__":

   r = NewRectangle()

   r.width = 3

   r.length = 4

   print(r.size)

   r.size = 30,40

   print(r.width)

   print(r.length)

Python

我们来看一下运行的结果:

(3, 4)

30

40

Python

我们可以看到,除了类的写法变了以外,调用的方式没有变,结果也没有变。

请先 登录 后评论