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

  • 相关阅读:
    双连通分量
    题解 骰子
    2020 最新 Kubernetes实战指南:从零到架构师的进阶之路
    kubernetes实战(二十八):Kubernetes一键式资源管理平台Ratel安装及使用
    新书推荐《再也不踩坑的Kubernetes实战指南》
    为什么要用Kubernetes?
    Kubernetes实战指南(三十一):零宕机无缝迁移Spring Cloud至k8s
    kubernetes实战(三十一):Prometheus监控Windows主机
    kubernetes实战(三十):CentOS 8 二进制 高可用 安装 k8s 1.17.x
    kubernetes实战(二十九):Kubernetes RBAC实现不同用户在不同Namespace的不同权限
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9156079.html
Copyright © 2011-2022 走看看