Python类和实例的属性机制原理详解


Posted in Python onMarch 21, 2020

实例是具象化的类,它可以作为类访问所有静态绑定到类上的属性,包括类变量与方法,也可以作为实例访问动态绑定到实例上的属性。

实例1:

class A:
  work = list("hello")
  kind = list("world")
  another = 1

  def test1(self):
    print(self.work, self.kind, self.another)
    self.work[0], self.kind [0] = "t", "t"
    self.another += 1
    print(A.work, A.kind, A.another)
if __name__ == "__main__":
  a = A()
  a.test1()

输出结果:

['h', 'e', 'l', 'l', 'o'] ['w', 'o', 'r', 'l', 'd'] 1
['t', 'e', 'l', 'l', 'o'] ['t', 'o', 'r', 'l', 'd'] 1

test1中演示了实例对类变量的访问与修改,从输出结果可以看到,类变量work和kind的列表被修改了,而another的值没有发生变化,说明如果类变量是可变的,那么可以通过实例来对类变量进行修改,如果类变量不可变,那么实例无法修改类变量。

实例2:

class A:
  work = list("hello")
  kind = list("world")
  another = 1

  def test2(self):
    A.work, A.kind = "hello", " world"
    A.another += 2
    print(self.__dict__)
    print(self.work, self.kind, self.another)
    A.test2 = 13
    print(self.test2)
if __name__ == "__main__":
  a = A()
  a.test2()

输出结果:

 {'another': 2}
 hello world 2
 13

test2说明了实例访问类变量与方法的机制,在test1中,已经给实例动态绑定了一个another的属性,值为2(因为有赋值语句)。在self.__dict__中可以看到确实出现了实例属性another。

在使用实例访问属性(变量与方法)时,如果在实例的属性集里没有找到对应的属性,那么就会到类的属性集里找对应的属性。self.work和self.kind和类变量保持一致,说明并没有事先在实例与类变量之间建立引用,而是动态查找的。

class A:
  work = list("hello")
  kind = list("world")
  another = 1

  def test3(self):
    print(self.__dict__)
    self.w, self.k = 0, 1
    print(self.__dict__)
    self.work, self.kind = 4, 4
    print(self.__dict__)
    self.test1 = 12
    print(self.__dict__)
    try:
      self.test1()
    except:
      print("test1 is not a bound method")
if __name__ == "__main__":
  a = A()
  a.test3()

输出结果:

 {'another': 2}
 {'another': 2, 'w': 0, 'k': 1}
 {'another': 2, 'w': 0, 'k': 1, 'work': 4, 'kind': 4}
 {'another': 2, 'w': 0, 'k': 1, 'work': 4, 'kind': 4, 'test1': 12}
 test1 is not a bound method

self.__dict__中保存了动态绑定到实例的变量与方法,只要出现了赋值语句,都是动态绑定属性。如果动态绑定的属性与类的变量或方法同名,在查找过程中就会覆盖类的变量和方法。

总结

1. 动态绑定到实例的属性位于self.__dict__中

2. 出现self.attribute = XXX之类的赋值语句都是在往实例上动态绑定属性

3. 实例查找属性的流程:self.work -> self.__dict__["work"] or cls.work,这是一个动态的过程,实例中的同名属性会覆盖类变量或方法,类变量或方法的修改会实时影响实例查找属性的结果

4. 如果类变量是可修改的,如列表,字典等,可以通过实例来修改类变量,方法是不可修改的,故无法通过实例修改方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python中使用判断语句和循环的教程
Apr 25 Python
Python lxml模块安装教程
Jun 02 Python
学习python 之编写简单乘法运算题
Feb 27 Python
简单谈谈python的反射机制
Jun 28 Python
浅谈终端直接执行py文件,不需要python命令
Jan 23 Python
Python利用operator模块实现对象的多级排序详解
May 09 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
Jan 04 Python
django 将model转换为字典的方法示例
Oct 16 Python
python调用opencv实现猫脸检测功能
Jan 15 Python
简单了解python的内存管理机制
Jul 08 Python
python实现大量图片重命名
Mar 23 Python
利用python实现汉诺塔游戏
Mar 01 Python
Python生成器常见问题及解决方案
Mar 21 #Python
Python作用域与名字空间原理详解
Mar 21 #Python
Python小整数对象池和字符串intern实例解析
Mar 21 #Python
Python描述符descriptor使用原理解析
Mar 21 #Python
Python如何省略括号方法详解
Mar 21 #Python
Python如何使用bokeh包和geojson数据绘制地图
Mar 21 #Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 #Python
You might like
PHP 选项及相关信息函数库
2006/12/04 PHP
PHP数组交集的优化代码分析
2011/03/06 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
FastCGI 进程意外退出造成500错误
2015/07/26 PHP
PHP设计模式之命令模式示例详解
2020/12/20 PHP
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
jQuery过滤选择器:not()方法使用介绍
2014/04/20 Javascript
关于JS变量和作用域详解
2016/07/28 Javascript
jquery属性,遍历,HTML操作方法详解
2016/09/17 Javascript
浅谈AngularJs指令之scope属性详解
2016/10/24 Javascript
微信小程序 wx.uploadFile无法上传解决办法
2016/12/14 Javascript
bootstrap手风琴制作方法详解
2017/01/11 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
Angular2平滑升级到Angular4的步骤详解
2017/03/29 Javascript
JS数组去重常用方法实例小结【4种方法】
2018/05/28 Javascript
打通前后端构建一个Vue+Express的开发环境
2018/07/17 Javascript
详解微信小程序canvas圆角矩形的绘制的方法
2018/08/22 Javascript
angular6 填坑之sdk的方法
2018/12/27 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
基于vue+element实现全局loading过程详解
2020/07/10 Javascript
使用eslint和githooks统一前端风格的技巧
2020/07/29 Javascript
JavaScript原生数组函数实例汇总
2020/10/14 Javascript
[49:08]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
使用python画个小猪佩奇的示例代码
2018/06/06 Python
python中 * 的用法详解
2019/07/10 Python
在TensorFlow中实现矩阵维度扩展
2020/05/22 Python
python json.dumps() json.dump()的区别详解
2020/07/14 Python
python中@contextmanager实例用法
2021/02/07 Python
HTML5 对各个标签的定义与规定:body的介绍
2012/06/21 HTML / CSS
用html5的canvas和JavaScript创建一个绘图程序的简单实例
2016/07/06 HTML / CSS
HTML5 背景的显示区域实现
2020/07/09 HTML / CSS
美国新蛋IT数码商城:Newegg.com
2016/07/21 全球购物
房产买卖委托公证书
2014/04/04 职场文书
研发工程师岗位职责
2014/04/28 职场文书
铁人纪念馆观后感
2015/06/16 职场文书