python魔法方法之__setattr__()
作者:机器学习入坑者 发布时间:2021-06-06 13:27:47
前言:
python提供了诸多的魔法方法,其中__setattr__()方法主要用于类实例进行属性赋值,其定义在Object类官方提供的说明如下:
Called when an attribute assignment is attempted.
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__属性中。
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类重载了__setattr__()方法,并且将实例的属性和属性值作为__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'}
**************************************************
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__字典中。
来源:https://zhuanlan.zhihu.com/p/101004827
猜你喜欢
- 本文实例为大家分享了python实现电子词典的具体代码,供大家参考,具体内容如下# -*- coding: utf-8 -*-#youdan
- 今天第一次玩SQL Server 2005,需要配置远程连接。我废话少说,直入主题,总结下我从新手立场在win2003 server环境下去
- Oracle数据库作为大型数据库管理系统,近年来一直占有世界上高端数据库的最大份额,其强大而完善的数据库管理功能,以及ORACLE公司推陈出
- 基本信息程序包名称:基于.net开发的遵循web标准的个人站点程序包下载开发者主页:www.ceocio.net软件大小:1.84mb安装环
- SQL Server创建临时表:创建临时表 方法一: &n
- Microsoft Visual C++ 14.0 is required. Get it with “Microsof
- 代码如下:--CAST 和 CONVERT 函数 Percentage DECLARE @dec decimal(5,3), @var va
- 如果PyPi上搜html2text的话,找到的是另外一个库:Alir3z4/html2text。这个库是从aaronsw/html2text
- 本文实例讲述了Python实现的多叉树寻找最短路径算法。分享给大家供大家参考,具体如下:多叉树的最短路径:思想: &n
- 但是,具有identity特性的字段,不需要具有唯一性,更不必须是主键。 可以通过,set identity_insert tablenam
- 这篇文章主要介绍了python中如何使用insert函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- python生成遍历暴力破解密码(这里已遍历暴力破解rar为例,只提供生成密码以及遍历密码)这个也就是提供一个思路,需求是这样的,我XX的闺
- 第一次使用csdn写一个文章,如果有什么写的不对的地方,欢迎在下面评论指正,谢谢各位。1.明确要使用的包首先就是opencv的函数库,还有p
- 导读:在Java中我们使用try-catch进行异常处理,同样的JavaScript也提供了和异常处理类似的异常处理机制,本节我们将对Jav
- 前言我们在工作中的时候,会有这种需求:用户上传一个格式固定excel表格到网站上,然后程序负债解析内容并进行处理。我最近在工作中就遇到了,所
- vue 使用微信jssdk1、引入weixin-js-sdknpm install weixin-js-sdk使用文档 https://ww
- 二进制包方式安装一、首先检查服务器上是否安装有mysql:第一步:查看mysql安装版本rpm -qa|grep -i mysql第二步:卸
- 本节要讲解如下图所示的滑块验证码(更为复杂的滑动拼图验证码在下一篇介绍)。这种验证码机制比较简单:将滑块拖动到滑轨的最右端即可完成验证,如下
- 项目实现利用face++开发一个课堂签到的软件,实现面向摄像头即可完成记录学号、姓名和时间的签到工作。项目架构项目使用场景代码:流程代码,主
- 废话不多说,直接上代码吧~model.zero_grad()optimizer.zero_grad()首先,这两种方式都是把模型中参数的梯度