开发者

python魔法方法之__setattr__()

开发者 https://www.devze.com 2022-12-12 13:40 出处:网络 作者: 机器学习入坑者
目录前言:1、实例属性管理__dict__2、__setattr__()与__dict__3、重载__setattr__()必须谨慎总结:前言:
目录
  • 前言:
  • 1、实例属性管理__dict__
  • 2、__setattr__()与__dict__
  • 3、重载__setattr__()必须谨慎
  • 总结:

前言:

python提供了诸多的魔法方法,其中__setattr__()方法主要用于类实例进行属性赋值,其定义在Object类官方提供的说明如下:

Called when an attribute assignment is attemphttp://www.cppcns.comted. 

This is called instead of the normal mechanism (i.e. store the value in the instance dictionary).

 name is the attribute name, value is the value to be assigned to it.

简单的说,__setattr_编程客栈_()在属性赋值时被调用,并且将值存储到实例字典中,这个字典应该是self的__dict__属性。即:在类实例的每个属性进行赋值时,都会首先调用__setattr__()方法,并在__setattr__()方法中将属性名和属性值添加到类实例的__dict__属性中。

python魔法方法之__setattr__()

1、实例属性管理__dict__

下面的测试代码中定义了三个实例属性,每个实例属性注册后都print()此时的__dict__

代码如下:

class AnotherFun:
  def __init__(self):
    self.name = "Liu"
    print(self.__dict__)
    self.age = 12
    print(self.__dict__)
    self.male = True
    print(self.__dict__)
another_fun = AnotherFun()

得到的结果显示出,每次实例属性赋值时,都会将属性名和对应值存储到__dict__字典中:

{'name': 'Liu'}
{'name': 'Liu', 'age': 12}
{'name': 'Liu', 'age': 12, 'male': True}

2、__setattr__()与__dict__

由于每次类实例进行属性赋值时都会调用__setattr__(),所以可以重载__setattr__()方法,来动态的观察每次实例属性赋值时__dict__()的变化。下面的Fun类重载了__seta编程客栈ttr__()方法,并且将实例的属性和属性值作为__dict__的键-值对:

class Fun:
  def __init__(self):
    self.name = "Liu"
    self.age = 12
    self.male = True
   
  def __setattr__(self, key, value):
    print("*"*50)
    print("setting:{}, with:{}".format(key[], value))
    print("current __dict__ : {}".format(self.__dict__))
    # 属性注册
    self.__dict__[key] = value
fun = Fun()  

通过在__setattr__()中将属性名作为key,并将属性值作为value,添加到了__dict__中,得到的结果如下:

**************************************************

setting:name,  with:Liu

current __dict__ : {}

**************************************************

setting:age,  with:12

current __dict__ : {'name': 'Liu'}

*******************************************http://www.cppcns.com*******

setting:male,  with:True

current __dict__ : {'name': 'Liu', 'age': 12}

可以看出,__init__()中三个属性赋值时,每次都会调用一次__setattr__()函数。

3、重载__setattr__()必须谨慎编程客栈

由于__setattr__()负责在__dict__中对属性进行注册,所以自己在重载时必须进行属性注册过程,下面是__setattr__()不进行属性注册的例子:

class NotFun:
  def __init__(self):
    self.name = "Liu"
    self.age = 12
    self.male = True
 
  def __setattr__(self, key, value):
    pass
not_fun = NotFun()
print(not_fun.name)

由于__setattr__中并没有将属性注册到__dict__中,所以not_fun对象并没有name属性,因此最后的print(not_fun.name)会报出属性不存在的错误:

AttributeError                            Traceback (most recent call last)

<ipython-input-21-6158d7aaef71> in <module>()

      8         pass

      9 not_fun = NotFun()

---> 10 print(not_fun.name)

AttributeError: 'NotFun' object has no attribute 'name'

所以,重载__setattr__时必须要考虑是否在__dict__中进行属性注册。

总结:

python的实例属性的定义、获取和管理可以通过__setattr__()和__dict__配合进行,当然还有对应的__getattr__()方法,本文暂时不做分析。__setattr__()方法在类的属性赋值时被调用,并通常需要把属性名和属性值存储到self的__dict__字典中。

到此这篇关于python魔法方法之__setattr__()的文章就介绍到这了,更多相关python魔法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号