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:类属性仅与其类相绑定,类数据属性仅当需要有更加“静态”数据类型时才变得有用,这种属性是静态变量.它们表示这些数 ...
随机推荐
- knockout.js模板绑定之利用Underscore.js模板引擎示例
View代码 <h1>People</h1> <ul data-bind="template: { name: 'peopleList' }"> ...
- jmap查看内存使用情况与生成heapdump
jmap查看内存使用情况与生成heapdump 如果想分析自己的JAVA Application时,可以使用jmap程序来生成heapdump文例: jmap -heap 1234 (1234为进程 ...
- android开发(39) 使用android系统的账户中心管理账
在android的系统设置页,有个“账户”分组,里面有很多的账户,很多app都使用了这个账户系统,比如“谷歌”,“淘宝”,“微信”,“华为”等.这些都是大公司呢,有没有可能我们也使用这个,让我们的软件 ...
- 【jquery】ajax 请求成功后新开窗口被拦截解决方法
问题: 前面开发项目时碰到一个问题,ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是很可惜被浏览器给拦截了,怎么解决这个问题呢? 分析: 浏览器之所以 ...
- windows10删除开始菜单中的xbox、人脉、邮件等应用
1.右键单击PowerShell,选择“以管理员身份运行” 2.输入下面的命令回车,会列出系统中所有已安装应用列表. Get-AppxPackage -AllUsers 从列表中找到你要卸载的应用,并 ...
- 史上最全 Css Hack汇总
前言 每次要找个东西都得慢慢去翻自己收集的一些东西,每次都是那么花时间,再加上有时存放时间久远就忘了当时是存在哪了,为了方便查询及阅读,决定把一些Css Hack 收集起来... 1.区别不同浏览器, ...
- Windows 7 incorrectly reports "No Internet Access"
PROBLEM DESCRIPTION Windows 7 may sometimes report that it has "No Internet Access"; this ...
- USB2.0学习笔记连载(四):安装Cypress官网套件
上一篇博客大概讲了一下USB通用驱动程序的解析.笔者使用Cypress官网给定的资料去完成USB驱动开发.官网资料地址:http://www.cypress.com/?rID=14321 下载如下图的 ...
- ubantu linux的bash shell初接触
本人是Linux初习者,同时也刚刚开始学习,将我的学习成长记录下来,来和大家一同分享! 我用的系统是Ubuntu 12.04,脚本编辑器用的是VIM,觉得很顺手!Shell语言用的是Bash Shel ...
- Maven项目模板
maven 使用 Archetype 概念为用户提供不同类型的项目模板,它是一个非常大的列表(614个数字). maven 使用下面的命令来帮助用户快速开始构建一个新的 Java 项目. mvn ar ...