Python学习笔记——类属性和实例属性
2017-06-09 00:13
423 查看
Python学习笔记——类属性和实例属性的区别
访问特性
首先我们以Test类为例:
class Test(object): #类属性 a = 100 def __init__(self, b): #实例属性 self.b = b t = Test(100) #通过实例化对象访问 类属性 print("t.a = %d"%t.a) #通过类名访问 类属性 print("Test.a = %d"%Test.a) #通过实例化对象访问 实例属性 print("t.b = %d"%t.b) #通过类名访问 实例属性 print("Test.b = %d"Test.b) #error 无法通过(类名.属性名)的方式访问实例属性
从上面这里例子我们可以知道:
对于类属性我们可以通过类名及实例对象去访问,即:
类名.类属性,
实例.类属性
两种方式访问。
属性
1:实例属性:
在__init__(self,…)中初始化
内部调用时都需要加上self.
外部调用时用实例化对象.属性名
2:类属性:
在__init__()外初始化
在内部用类名.类属性名调用
外部既可以用类名.类属性名又可以用实例化对象.类属性名来调用
3:私有属性:
1):单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改
2):双下划线__开头:外部不可通过实例化对象.属性名来访问或者更改
实际将其转化为了_类名_属性名,只是在内部将变量名修改了,我们仍让可以通过._类名_属性名访问
如图:
类属性的修改
类属性是所有实例共有的属性即静态属性,类似JAVA/C++中static,但是仅仅只是类似。我们知道在JAVA中所有类对象共享static内数据的内存,也就是说通过修改static中的值会导致其他对象中static值
同样被修改,但在Python中并不是这样。我们看下面这个例子:
class Test(object): a = 100 def __init__(self): pass t1 = Test() t2 = Test() #1.通过实例对象t1修改类属性的值 print("修改前:t1.a = %d, t2.a = %d, Test.a = %d"%(t1.a, t2.a, Test.a)) t1.a += 100 print("修改后:t1.a = %d, t2.a = %d, Test.a = %d"%(t1.a, t2.a, Test.a))
output:
>>>修改前:t1.a = 100, t2.a = 100, Test.a = 100
>>>修改后:t1.a = 200, t2.a = 100, Test.a = 100
很明显,我们通过实例对象修改类属性的值,并没有在全局范围奏效,只是对于t1中的类属性有所不同。
那接下来通过类名修改类属性看看会有什么结果,
class Test(object): a = 100 def __init__(self): pass t1 = Test() t2 = Test() #1.通过类名修改类属性的值 print("修改前:t1.a = %d, t2.a = %d, Test.a = %d"%(t1.a, t2.a, Test.a)) Test.a += 100 print("修改后:t1.a = %d, t2.a = %d, Test.a = %d"%(t1.a, t2.a, Test.a))
output:
>>>修改前:t1.a = 100, t2.a = 100, Test.a = 100
>>>修改后:t1.a = 200, t2.a = 200, Test.a = 200
通过类名修改的类属性,在全局范围奏效,也就是说确实修改了类属性的值,在实例对象中我们看到a的值全部被
修改。实际上这就是类属性的持久性从这个例子看,实例对象确实和类对象共有相同的类属性,那么为什么通过实例对象无法在全局范围修改
呢?
实际上,这就是关于作用域的问题,看下面这张图
也就是说,实例对象仅能访问类属性,即只能get不能set。我们怎么证明这一点呢?
我们知道dir()是Python中的内建函数
通过调用dir()函数显示出对象或者类的所有属性
我们通过输出__dict__属性观察变化,类输出的是全局的函数,变量等信息。
对象输出的只是对象拥有的普通变量。这样可以其他信息的干扰。
class Test(): a = 100 def __init__(self): pass t1 = Test() #打印修改前的类和实例对象中的变量,函数 print(Test.__dict__) print("\n\n\n") print(t1.__dict__) t1.a += 100 #通过修改实例对象修改a的值吗,并打印类和实例对象中的变量,函数 print(Test.__dict__) print("\n\n\n") print(t1.__dict__) print("\n\n\n")
output如图:
确实,我们无法通过实例对象对类属性进行修改,真的是这样吗?
接下来看下面这段代码,
class Test(object): dict_a = {1:"leo"} def __init__(self): pass t1 = Test() print("--------Before--------") print(t1.__dict__) print(Test.__dict__) t1.dict_a[2] = "mike" print("--------After-------") print(t1.__dict__) print(Test.__dict__)
Output如图:
我们发现,通过实例对象添加的键值对 2:”mike”并没有创建实例属性,这是因为字典为可变类型,而数
字是不可变类型,因此无法通过这种方式修改。所以在实际开发中应该避免通过实例对象去修改类属
性。
相关文章推荐
- 【Python】学习笔记——-7.5、实例属性和类属性
- python进阶学习笔记(四)——python中访问限制、创建类属性、定义实例方法、定义类方法、类的继承
- python学习笔记-实例方法、类方法、静态方法、属性方法
- python进阶学习笔记(五)——创建实例属性、初始化实例属性
- python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性
- 初学Python的学习笔记9----面向对象编程(获取对象信息、实例属性和类属性)、面向对象高级编程(使用__slots__、使用@property)
- Python学习26:类属性vs实例属性
- linux下python学习笔记(十四)之备份实例2
- 自定义属性之图片切换实例——代码简化、函数合并——JS学习笔记2015-5-30(第43天)
- python基础教程_学习笔记11:魔法方法、属性和迭代器
- 自定义属性之图片切换实例——初始化——JS学习笔记2015-5-28(第41天)
- Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
- j2me学习笔记【12】——游戏操作Canvas类的up、down、left、right、fire属性使用实例
- Python学习:给类的实例绑定属性和方法
- python3.4学习笔记(十) 常用操作符,条件分支和循环实例
- 【python学习笔记】python中的模块,类,函数,对象,实例(与JAVA的比较)
- Python ORM框架SQLAlchemy学习笔记之数据查询实例
- linux下python学习笔记(十三)之备份实例1
- Ext学习笔记 - NameSpace,类实例属性,类实例方法,类静态方法
- Python ORM框架SQLAlchemy学习笔记之关系映射实例