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 23 Python
python网络编程学习笔记(四):域名系统
Jun 09 Python
django接入新浪微博OAuth的方法
Jun 29 Python
python使用matplotlib绘制柱状图教程
Feb 08 Python
Python使用PyCrypto实现AES加密功能示例
May 22 Python
Python聊天室程序(基础版)
Apr 01 Python
Python wxPython库消息对话框MessageDialog用法示例
Sep 03 Python
Python3 SSH远程连接服务器的方法示例
Dec 29 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
Oct 23 Python
python3爬取torrent种子链接实例
Jan 16 Python
手把手教你安装Windows版本的Tensorflow
Mar 26 Python
python pandas 解析(读取、写入)CSV 文件的操作方法
Dec 24 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支持中文字符串分割的函数
2015/05/28 PHP
学习PHP Cookie处理函数
2016/08/09 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
jquery遍历数组与筛选数组的方法
2013/11/05 Javascript
jQuery自定义事件的简单实现代码
2014/01/27 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/06/05 Javascript
JavaScript中使用Object.prototype.toString判断是否为数组
2015/04/01 Javascript
JavaScript对象参数的引用传递
2016/01/14 Javascript
Jquery 整理元素选取、常用方法一览表
2016/11/26 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
js移动端图片压缩上传功能
2020/08/18 Javascript
vue-cli的eslint相关用法
2017/09/29 Javascript
微信小程序顶部可滚动导航效果
2017/10/31 Javascript
关于vue中的ajax请求和axios包问题
2018/04/19 Javascript
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
基于React Native 0.52实现轮播图效果
2020/08/25 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
2019/03/09 Javascript
vue项目中定义全局变量、函数的几种方法
2019/11/08 Javascript
js实现div色块碰撞
2020/01/16 Javascript
使用python绘制人人网好友关系图示例
2014/04/01 Python
Python pyinotify模块实现对文档的实时监控功能方法
2018/10/13 Python
利用python实现在微信群刷屏的方法
2019/02/21 Python
Python Spyder 调出缩进对齐线的操作
2021/02/26 Python
html5应用缓存_动力节点Java学院整理
2017/07/13 HTML / CSS
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
装潢设计实习自我鉴定
2013/09/19 职场文书
工作中个人的自我评价
2013/12/31 职场文书
护士演讲稿范文
2014/01/05 职场文书
土建专业毕业生自荐书
2014/07/04 职场文书
岗位工作说明书
2014/07/29 职场文书
小学教师暑期培训方案
2014/08/28 职场文书
个人自查自纠材料
2014/10/14 职场文书
大学生自荐信怎么写
2015/03/26 职场文书
销售内勤岗位职责范本
2015/04/13 职场文书
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏