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

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)

in ()

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魔法方法之__setattr__()相关推荐

  1. python 内置属性__setattr___python 自定义属性访问 __setattr__, __getattr__,__getattribute__, __call__...

    object._getattr_(self, name) __gettattr__:如果某个类定义了这个方法,并且在该类的对象的字典中又找不到相应的属性时候,那么该方法会被调用. 实例instance ...

  2. python 内置属性__setattr___python 属性四种管理方法property,descriptor, __get/setattr__, __getatribute __...

    总是在代码里面看到,__set__,__get__,__getattr__,__setattr__,__getatribute__,property. 这些东东的通常作用基本是属性拦截,这里做个笔记记 ...

  3. python内置属性与内置方法

    一.类方法 类方法:把类看作成一个对象 #语法: #@classmethod----由@开头的叫做装饰器或者修饰器 #def 类方法名(cls,形参): 类方法可以直接使用----->类对象.类 ...

  4. python内置属性类_Python内置类属性,元类研究

    Python内置类属性 我觉得一切都是对象,对象和元类对象,类对象其实都是一样的,我在最后进行了证明,但是只能证明一半,最后由于元类的父类是type,他可以阻挡对object属性的访问,告终 __di ...

  5. 列举5个python内置函数和使用方法_python内置函数是什么

    python内置函数如下表 用法及说明 1.abs(),返回数字的绝对值. 2.all(),如果集合中所有元素是true或集合为空集合,返回True. 3.any(),如果集合中有一项元素是true, ...

  6. 列举至少五个python内置函数和使用方法_Python内置函数 next的具体使用方法 Python中seek和next区别...

    python列表本来没有next方法,为什么用iter函数生...对list用__dir__()发现没有next方法,但是用iter()生成迭代器,对该迭代next是进行迭代的方法,只有迭代器和生成器 ...

  7. 列举5个python内置函数和使用方法_Python基础-----函数、内置函数、递归等练习

    !/usr/bin/env python -*- coding:utf-8 -*- ########################################################## ...

  8. python内置函数之len()方法

    文章目录 len()方法 描述 语法 参数 返回值 实例 len()方法 描述 Python len() 方法返回对象(字符.列表.元组等)长度或项目个数. 语法 len()方法语法: len( s ...

  9. Python 内置方法和属性应用:反射和单例

    1. 前言 python除了丰富的第三方库外,本身也提供了一些内在的方法和底层的一些属性,大家比较常用的如dict.list.set.min.max.range.sorted等.笔者最近在做项目框架时 ...

最新文章

  1. 用Python解“求特殊方程得正整数解”题
  2. 初识Java-IO流
  3. salmap绕waf
  4. jsp超链接中怎么跳转页面跳转页面_在页面点击超链接跳到别的页面,方法是什么?...
  5. 安卓模拟器获取服务器信息出错,安卓模拟器客户端与服务器不同步
  6. 设计一个按优先数调度算法实现处理器调度的程序_计算机中的程序都是怎么运行的,来深入了解一下吧...
  7. 一步步编写操作系统 29 cpu缓存简介
  8. HTML5触摸事件演化tap事件
  9. 通过负载均衡器+域名实现容灾切换-(8)基于DNS解析的GSLB在BS架构中应用实践(转)(2)...
  10. 【转】glTexImage2D()和gluBuild2DMipmaps() [将载入的位图文件(*.bmp)转换成纹理贴图]+glTexParameteri()纹理过滤函数...
  11. 程序员最艰巨的十大任务
  12. 【汇编基础】SIMD除法的实现
  13. 激活Maven profile的几种方式
  14. iOS - Swift 与 Objective-C 互相操作
  15. DOS下常用网络相关命令解释(华为培训资料)
  16. JSK-11 移除数组中的重复元素【入门】
  17. Java 最长递增子序列_最长递增子序列问题 Java
  18. 微信小程序游戏开发│石头剪刀布游戏(附源码)
  19. 全球四大卫星导航系统
  20. Unity应该怎样学习

热门文章

  1. 细胞膜包裹布洛芬/奥美拉唑/氨甲喋呤/阿霉素/CPT喜树碱(细胞膜仿生介绍)
  2. pyqt+vlc 播放rtsp/rtmp地址并嵌入任意frame中
  3. 建群网培PMP每日一练
  4. linux栈溢出检测原理,操作系统栈溢出检测之ucosII篇
  5. 你连对外接口签名都不会知道?有时间还是要学习学习。
  6. 基于IC5000烧录器使用winIDEA烧写+调试程序(S32K324的软件烧写与调试)
  7. python制作窗口界面_python爬虫如何制作可视化界面?(pyqt5环境配置篇)
  8. Google Sites 简介
  9. group lasso matlab,一种利用肠道微生物菌群评价生猪个体蛋白营养状态的方法与流程...
  10. RFID停车场收费系统