zoukankan      html  css  js  c++  java
  • 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就都是独立的了,添加订阅者到苍老师的列表,范老师的列表不会跟着变化。

  • 相关阅读:
    JavaScript操作符instanceof揭秘
    Linux打开txt文件乱码的解决方法
    Working copy locked run svn cleanup not work
    poj 2299 UltraQuickSort 归并排序求解逆序对
    poj 2312 Battle City 优先队列+bfs 或 记忆化广搜
    poj2352 stars 树状数组
    poj 2286 The Rotation Game 迭代加深
    hdu 1800 Flying to the Mars
    poj 3038 Children of the Candy Corn bfs dfs
    hdu 1983 Kaitou Kid The Phantom Thief (2) DFS + BFS
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9156079.html
Copyright © 2011-2022 走看看