python 类属性 、实例属性,可变数据结构作为类属性需要注意的地方
1、一些经典的python错误不去阅读和不重视,就会把错误的做法带入到实际项目中来,甚至造成难以排查问题。
2、有一个大笨猪,按java写观察者模式,java写得是直接在类名下声明一个实例属性(不加static的),他直接翻译成python后,也是直接写在类名下面,这就是大坑了。
java里面在类名下面声明的带static为类属性,不带static为实例属性,python如果直接写在类名下面的属性,一律都是类属性,实例属性一般都是在init里面写的,带self字眼的变量。

#coding:utf-8 class A():
x_list = [] a1 = A()
a1.x_list.append(1)
a2 = A()
print('第一个结果 -->',a2.x_list) class B():
x = 0 b1 = B()
b1.x =1
b2 = B()
print('第二个结果',b2.x) class C():
x = 0 c1 = C()
C.x =1
c2 = C()
print('第二个结果',c2.x)
运行结果是这样的。

对比 A B C三个类可以发现,类属性自己一份,实例属性默认等于类属性。
比如B类,实例b1的x默认等于0,当赋值为1时候,b1的x就等于1了,此时B类的属性x仍然等于0,b2实例的属性x也是等于0。
c类,直接改变C类的x属性,则C的x变为1了,如果实例化一个新的c2,默认就等于1了。
B和C的这种操作是很多案例上都有的,烂大街了,一定需要查看常见容易错误的案例。
3. 最主要还是A类,A类的x_list是一个列表,列表是可变数据结构,用可变次数据结构作为类属性,就要很小心了,即使是用实例a1操作x_list,仍然会影响A的属性x_list和a2的属性x_list。当可变元素作为类属性时候,操作 a.x_list和A.x_list是等效的,都是互相影响的。
不可变数据结构例子:
a_str = ‘hello’
b_str = a_str
b_str = a_str + 'world'
最终a的值是hello ,b的值是hello world。
可变的数据结构例子:
a_list = ['hello']
b_list = a_list
b_list + = ['world']
最终a_list和b_list的值都是['hello', 'world']
4 .回到题目就是,在观察者模式中,如果把订阅者添加到类属性x_lsit列表,那么所有的发布者都共享了所有的订阅者。
比如小明、小军订阅了苍老师,小红 小黄订阅了范老师,但苍老师更新电影时候,由于共享了订阅者,导致小红和小黄也收到新片通知了,这显然是个错误。
所以苍老师和范老师的x_list必须是独立的,需要写在__init__里面,写成self.x_list,这样苍老师和范老师的x_list就都是独立的了,添加订阅者到苍老师的列表,范老师的列表不会跟着变化。
python 类属性 、实例属性,可变数据结构作为类属性需要注意的地方的更多相关文章
- python 零散记录(七)(下) 新式类 旧式类 多继承 mro 类属性 对象属性
python新式类 旧式类: python2.2之前的类称为旧式类,之后的为新式类.在各自版本中默认声明的类就是各自的新式类或旧式类,但在2.2中声明新式类要手动标明: 这是旧式类为了声明为新式类的方 ...
- Python中类的声明,使用,属性,实例属性,计算属性及继承,重写
Python中的类的定义以及使用: 类的定义: 定义类 在Python中,类的定义使用class关键字来实现 语法如下: class className: "类的注释" 类的实体 ...
- python类和实例以及__call__/__del__
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...
- 动态修改Python类和实例的方法(转)
相信很多朋友在编程的时候都会想修改一下已经写好的程序行为代码,而最常见的方式就是通过子类来重写父类的一些不满足需求的方法.比如说下面这个例子. class Dog: def bark(self): p ...
- python 动态修改 类和实例 的方法
相信很多朋友在编程的时候都会想修改一下已经写好的程序行为代码,而最常见的方式就是通过子类来重写父类的一些不满足需求的方法.比如说下面这个例子. class Dog: def bark(self): p ...
- C#类的实例
一.C#类的实例 类的实例其实就是类的对象.定义类之后即可声明类的对象,声明对象之后便可以访问对象的成员了. 语法格式如下: 类名 对象名; // 声明对象对象名 = new 类名() ...
- 在java的静态方法中访问类的实例成员
直接来看代码: public class Example { int x = 3;//类的实例变量,初始化值为3 static int y = 4;//类的静态变量,初始化值为4 public sta ...
- 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息
0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
- Python基础:17类和实例之一(类属性和实例属性)
1:类通常在一个模块的顶层进行定义.对于Python来说,声明与定义类是同时进行的. 2:类属性仅与其类相绑定,类数据属性仅当需要有更加“静态”数据类型时才变得有用,这种属性是静态变量.它们表示这些数 ...
随机推荐
- hive表增量抽取到oracle数据库的通用程序(一)
hive表增量抽取到oracle数据库的通用程序(二) sqoop在export的时候 只能通过--export-dir参数来指定hdfs的路径.而目前的需求是需要将hive中某个表中的多个分区记录一 ...
- OCiOS开发:音频播放器 AVAudioPlayer
简单介绍 AVAudioPlayer音频播放器可以提供简单的音频播放功能.其头文件包括在AVFoudation.framework中. AVAudioPlayer未提供可视化界面,须要通过其提供的播放 ...
- Java知多少(17)强调一下编程风格
讲完了Java的基础语法,大家就可以编写简单的程序代码了,这里有必要强调一下编程风格. 代码风格虽然不影响程序的运行,但对程序的可读性却非常重要.自己编写的程序要让别人看懂,首先在排版方面要非常注意. ...
- js类型判断的方法
var arr=[]; alert(Object.prototype.toString.call(arr)=='[object Array]');
- CSS非ASCII字符最佳实践
问题场景 在写样式时经常需要用到非ASCII字符的属性值,如下: ? 1 2 3 4 5 6 7 8 9 10 11 .hot_list .sign_discount:before { cont ...
- jQuery中ajax和post处理json的不同
近日在做门户的用户评论时,好长时间没有用jquery了正好用一下,没想到偷工用了post方法去处理ajax回调的json数据,死活取不到,后台就是有json返回了.不料这么小小一个问题挂了我好几个小时 ...
- 【协议学习】SIP基本场景分析
1.SIP业务基本知识 1.1 业务介绍 会话初始协议(Session Initiation Protocol)是一种信令协议,用于初始.管理和终止网络中的语音和视频会话,具体地说就是用来生成.修改和 ...
- 关于Unity中混合模式、Alpha测试、深度测试、通道遮罩、面剔除的使用----渲染通道通用指令(二)
混合模式 着色完成后,需要把颜色混合到帧缓冲区里面,涉及到源和目标. 1:在所有计算完成后,决定当前的计算结果输出到帧缓冲区时,如何混合源和目标,通常用来绘制半透明的物体;2: Blend Off 关 ...
- 【转】【Centos】nginx配置:location配置方法及实例详解
location匹配的是nginx的哪个变量? $request_uri location的匹配种类有哪些? 格式 location [ 空格 | = | ~ | ~* |^~ | !~ | !~* ...
- C++多线程中调用python api函数
错误场景:一直等待全局锁. 解决方法: 一.首先定义一个封装类,主要是保证PyGILState_Ensure, PyGILState_Release配对使用,而且这个类是可以嵌套使用的. #inclu ...