类属性和__init__的实例属性有何区别?进来了解一下吧
2024-08-29 22:54:49
真的是随笔写的一篇,以防日后记忆模糊,特此记录。大佬勿喷
疑问:类属性和实例属性有何区别?
正题,代码如下
age为People类的属性(称为类属性)
name是在__init__方法下,在创建实例对象的时候会自动调用,是动态创建的属性(称为实例属性)
class People:
age = 18 def __init__(self):
self.name = "小米" xm = People() print(People.age) # 类调用类属性
print(xm.age) # 实例对象调用类属性
print(xm.name) # 实例对象调用实例属性
代码似乎没什么问题,当然输出也没问题
18
小米
18
这个时候插入这样一段代码
print(People.name) # 类调用实例属性
奇怪的事情发生了,程序运行之后抛出以下异常
Traceback (most recent call last):
File "/Users/jinfukang/Desktop/metisPushRateMonitor/demo.py", line 14, in <module>
print(People.name) # 类调用实例属性
AttributeError: type object 'People' has no attribute 'name'
那么从异常信息看出说:People类没有name属性??
其实这是因为类在实例化之后只能通过实例对象去调用实例属性
继续,代码如下
class People:
age = 18 def __init__(self):
self.name = "小米" xm = People() People.age += 1 # 通过类调用类属性,使其属性值+1 print(xm.age) # 实例化对象调用类属性
print(People.age) # 类调用类属性
19
19
貌似没什么问题,继续,代码修改为如下
class People:
age = 18 def __init__(self):
self.name = "小米" xm = People() xm.age += 1 # 通过实例对象调用类属性,使其值+1
print(People.age) # 类调用类属性
print(xm.age) # 实例对象调用类属性 18
19
what???
使用类调用类属性+1,People.age和xm.age的值相等
使用实例对象调用类属性+1,People.age和xm.age的值竟然发生了变化。。。
按照咱们的期望,这2个值应该相等才对,可是为什么不一样了呢,接下来一起剖析一下
class People:
age = 18 def __init__(self):
self.name = "小米" xm = People() print("类调用类属性", id(People.age))
xm.age += 1 # 查看id,通过实例对象调用类属性,使其值+1
print("类调用类属性", id(People.age)) # 类调用类属性的,查看id
print("实例对象调用类属性", id(xm.age)) # 实例对象调用类属性,查看id 类调用类属性 4486466752
类调用类属性 4486466752
实例对象调用类属性 4486466784
由输出可以看出:
通过实例对象调用类属性+1前后,类调用类属性的身份证没有变化;实例对象调用的类属性身份证变了
这是不是可以说明 People.age和xm.age指向的不是同一个对象,为什么会这样呢,继续分析
这里就需要引入作用域的概念了: __init__的作用域只在自己的方法内,对于类属性它有访问的权限,但没有修改的权限
使用实例对象调用类属性使其值+1的时候,实例对象会在自己的作用域下创建一个age属性,将类属性的值拿过来并+1
对象调用age属性的时候,会先检查自己的作用域有没有age,如果有直接调用,所以类的age属性和对象的age属性的id发生变化
随笔记,有错误/遗漏的地方还请大佬指出,小弟感激不尽
最新文章
- 逻辑回归(Logistic Regression)
- ios基础篇(三十)—— AFNetworking的使用
- Android中常见功能包描述(转)
- 用 C# 轻松读取、改变文件的创建、修改、访问时间
- golang笔记——包
- Hadoop离线项目介绍(不包括程序)
- SSH配置动态数据源
- WPF 数据绑定
- C++ RAII手法实例,不使用智能指针
- NGUI系列教程二
- centos6.6 install
- 【jquery mobile笔记二】jquery mobile调用豆瓣api示例
- MFC不使用对话框资源模版创建对话框
- MFC-----在MFC中使用Picture控件加载任意图片
- js模块化开发——require.js的实战写法1
- canvas绘制多边形
- Ubuntu下搭建spark2.4环境(单机版)
- SpringCloud---网关概念、Zuul项目搭建(六)
- 【BZOJ3996】[TJOI2015]线性代数(最小割)
- css知识总结
热门文章
- Language Guide (proto3) | proto3 语言指南(十三)JSON映射
- JavaWeb——JSP内置对象application,JSP属性范围
- redis学习教程一《Redis的安装和配置》
- VMware虚拟机串口与宿主机进行传输验证
- CAS客户端和服务器配置https证书
- Linux常用命令详解(第一章)(ls、man、pwd、cd、mkdir、echo、touch、cp、mv、rm、rmdir、)
- ElasticSearch 安装与运行
- Codeforces Round #677 (Div. 3) G. Reducing Delivery Cost(dijkstra算法)
- C# ArrayList和List的区别
- SPU与SKU概念