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中的with语句与上下文管理器学习总结
Jun 28 Python
对pandas的dataframe绘图并保存的实现方法
Aug 05 Python
使用python编写udp协议的ping程序方法
Apr 22 Python
Python基于FTP模块实现ftp文件上传操作示例
Apr 23 Python
利用Python如何实现数据驱动的接口自动化测试
May 11 Python
Python工厂函数用法实例分析
May 14 Python
Python tkinter的grid布局及Text动态显示方法
Oct 11 Python
python实现三维拟合的方法
Dec 29 Python
Docker部署Python爬虫项目的方法步骤
Jan 19 Python
Pycharm如何运行.py文件的方法步骤
Mar 03 Python
Python制作表白爱心合集
Jan 22 Python
Python matplotlib绘制条形统计图 处理多个实验多组观测值
Apr 21 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
松下Panasonic RF-B65电路分析
2021/03/02 无线电
Ajax PHP简单入门教程代码
2008/04/25 PHP
php 动态多文件上传
2009/01/18 PHP
PHP 获取远程网页内容的代码(fopen,curl已测)
2011/06/06 PHP
destoon二次开发常用数据库操作
2014/06/21 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
2013/12/02 Javascript
浅谈NodeJS中require路径问题
2015/05/07 NodeJs
js实现字符串转日期格式的方法
2015/05/20 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
jquery实现可旋转可拖拽的文字效果代码
2016/01/27 Javascript
TypeOf这些知识点你了解吗
2016/02/21 Javascript
JS如何设置iOS中微信浏览器的title
2016/11/22 Javascript
Angular2平滑升级到Angular4的步骤详解
2017/03/29 Javascript
JavaScript中的FileReader图片预览上传功能实现代码
2017/07/24 Javascript
vue.js $refs和$emit 父子组件交互的方法
2017/12/20 Javascript
VueAwesomeSwiper在VUE中的使用以及遇到的一些问题
2018/01/11 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
Phaser.js实现简单的跑酷游戏附源码下载
2018/10/26 Javascript
postman自定义函数实现 时间函数的思路详解
2019/04/17 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
jQuery利用cookie 实现本地收藏功能(不重复无需多次命名)
2019/11/07 jQuery
Vue的全局过滤器和私有过滤器的实现
2020/04/20 Javascript
零基础写python爬虫之使用Scrapy框架编写爬虫
2014/11/07 Python
python创建和删除目录的方法
2015/04/29 Python
Python实现扣除个人税后的工资计算器示例
2018/03/26 Python
mac PyCharm添加Python解释器及添加package路径的方法
2018/10/29 Python
HTML5各种头部meta标签的功能(推荐)
2017/03/13 HTML / CSS
中国旅游网站:途牛旅游网
2019/09/29 全球购物
班委竞选演讲稿
2014/04/28 职场文书
运动会演讲稿200字
2014/08/25 职场文书
详细聊聊Oracle表碎片对性能有多大的影响
2022/03/19 Oracle
我的收音机情缘
2022/04/05 无线电
python实现学员管理系统(面向对象版)
2022/06/05 Python